【问题标题】:Communication link failure..Connection reset通信链路故障..连接重置
【发布时间】:2012-09-20 00:57:23
【问题描述】:

我的应用程序在使用 Hibernate 与 MySQL 数据库通信时偶尔会看到此异常。我尝试调整 C3p0 属性,但似乎不起作用。

这里是C3p0相关设置:

<property name="hibernate.c3p0.acquire_increment">2</property>
<property name="hibernate.c3p0.idle_test_period">60</property><!-- in seconds -->
<property name="hibernate.c3p0.min_size">2</property>
<property name="hibernate.c3p0.max_size">10</property>
<property name="hibernate.c3p0.max_statements">0</property>
<property name="hibernate.c3p0.timeout">180</property>
<property name="hibernate.c3p0.preferredTestQuery">select 1</property>

连接网址如下所示:

jdbc:mysql://<DB endpoint>?autoReconnect=true&useUniCode=true&characterEncoding=UTF-8&useSSL=true&requireSSL=true&verifyServerCertificate=false

堆栈跟踪是:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
Last packet sent to the server was 1549998 ms ago.

Caused by: javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLException: java.net.SocketException: 
Connection reset

我需要调整 MySQL 系统变量吗?任何指针我们如何避免这个异常?

谢谢 日腾德拉

【问题讨论】:

  • 当我检查我的日志时,似乎所有异常都来自一个过时的特定连接。这些异常在半小时内被抛出。我认为“idle_test_period”会每 60 秒检查一次连接的有效性。
  • 您能否将 testOnBorrow=”true” 添加到您的配置中,试试这个,让我们知道问题所在..
  • 日志也显示此消息:[托管:2 未使用:2 排除:1] 我想知道这里的“排除:1”是什么意思?
  • 我认为这是池中可用连接的状态
  • 'excluded' 表示 c3p0 注意到客户端使用 Connection 时发生的异常,并已将该 Connection 标记为销毁,而不是在将其签回池时重用。

标签: java mysql hibernate c3p0


【解决方案1】:

hibernate.c3p0.idle_test_period -- 或 c3p0.idleConnectionTestPeriod 将仅在连接空闲 60 秒时每 60 秒测试一次。如果你的应用非常活跃,它就不会闲置这么久。 c3p0 尝试注意到应用程序何时收到异常意味着连接应该失效,但这取决于异常的 SQLState,这在数据库/JDBC 驱动程序之间不一致并且不完全可靠。死连接很少能在多轮签入/签出后幸存下来,但根据您的设置,它可能会发生。

最简单的解决方案是将 c3p0.testConnectionOnCheckin 添加到您的配置中。这可确保无论连接是忙还是闲,连接都会在被允许进入池之前进行测试,而不会产生结帐测试的同步开销。

请看http://www.mchange.com/projects/c3p0/#configuring_connection_testing

还请确认您设置的配置参数正在通过底层连接池。 c3p0 在池初始化时将其配置转储到 INFO 级别的日志中:检查您的日志以验证您的设置是否与您认为的一样。 (或者,您可以在应用程序通过 jmx 运行时检查池。)

祝你好运!

【讨论】:

  • 谢谢史蒂夫。我将尝试这两个建议,确认 c3p0 设置被拾取和 testConnectionOnCheckin。
【解决方案2】:

听起来您的池中有一些连接并且只使用了其中的一部分。其中一些只是等待使用,然后变得陈旧(连接由于某种原因被重置 - 例如,数据库端的一些超时)。然后,当您尝试使用它们时,您会得到异常。

通常有几个选项可以解决此问题,例如,您可以在从池中检索连接之前测试连接 (hibernate.c3p0.testConnectionOnCheckout)

您还可以定期检查池中的连接状态和/或在签入时检查连接。见http://www.mchange.com/projects/c3p0/#configuring_connection_testing

如果没有帮助 - 整个堆栈跟踪可能会有用。

【讨论】:

猜你喜欢
  • 2012-11-16
  • 1970-01-01
  • 2021-11-21
  • 2021-03-27
  • 2018-12-24
  • 2012-05-27
  • 2018-07-15
  • 1970-01-01
  • 2018-02-17
相关资源
最近更新 更多