語言:javaEE
框架:spring mvc+spring+mybatis
數據庫:mysql8
WEB服務器:tomcat8
背景:
在試運營階段發現發生“連接超時”異常
拋出異常:
Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 353,479,051 milliseconds ago. The last packet sent successfully to the server was 353,479,078 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
; SQL []; The last packet successfully received from the server was 353,479,051 milliseconds ago. The last packet sent successfully to the server was 353,479,078 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.; nested exception is com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 353,479,051 milliseconds ago. The last packet sent successfully to the server was 353,479,078 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
原因分析:
MySQL服務器默認的“wait_timeout”是28800秒即8小時,意味着如果一個連接的空閑時間超過8個小時,MySQL將自動斷開該連接,而連接池卻認為該連接還是有效的(因為並未校驗連接的有效性),當應用申請使用該連接時,就會導致上面的報錯。
解決方案:
- 按異常信息所說,在MYSQL的JDBC連接串上加上autoReconnect=true
未能解決,據說這是針對mysql版本是5以前的。
2. 增加 MySQL 的 wait_timeout 屬性的值
方法1 修改配置文件my.ini中的wait_timeout和interactive_timeout
方法2 使用mysql命令
set global wait_timeout=2880000;
set global interactive_timeout=2880000;
未能解決,原因未知
3. 減少連接池內連接的生存周期:減少連接池內連接的生存周期,使之小於上一項中所設置的wait_timeout 的值。
方法:修改 c3p0 的配置文件,在 Spring 的配置文件中設置:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="maxIdleTime"value="1800"/> <!--other properties --> </bean>
未嘗試。
4. 每隔一段時間往數據庫發一條查詢語句,這樣使得數據庫空閑時間不會太長,而使得其自動關閉。
方法:在SqlMapConfig.xml的dataSource進行如下配置:
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="${jdbc.driverClassName}"/>
<property name="JDBC.ConnectionURL" value="${jdbc.url}"/>
<property name="JDBC.Username" value="${jdbc.username}"/>
<property name="JDBC.Password" value="${jdbc.password}"/>
<property name="Pool.PingEnabled" value="true"/>
<property name="Pool.PingQuery" value="select 1"/>
<property name="Pool.PingConnectionsOlderThan" value="0"/><br><br>
<property name="Pool.PingConnectionsNotUsedFor" value="3600000"/>
</dataSource>
開始的3行是關於數據庫連接信息的,不需要說明了。
Pool.PingEnabled:是用於設置開啟是否允許檢測連接狀態
Pool.PingQuery:是用於檢測連接的查詢語名,當然是越簡單越好
Pool.PingConnectionOlderThan:對持續連接時間超過設定值(毫秒)的連接進行檢測,我將其設置為0(不進行此項檢測),否則,iBatis在超過這個時間后,執行每個sql以前檢測連接,對於性能可能會有一定的影響。
Pool.PingConnectionsNotUsedFor:對空閑超過設定值(毫秒)的連接進行檢測,我設置為1小時(mysql缺省的關閉時間是8小時)
成功!
參考博文:https://blog.csdn.net/u012129031/article/details/72621288
http://hunterk.iteye.com/blog/544356
https://blog.csdn.net/qq_37164847/article/details/80780984
