com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

很長的報錯,截取

ERROR c.a.d.p.DruidDataSource - discard connection
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 44,866 milliseconds ago.  The last packet sent successfully to the server was 0 milliseconds ago.
	at sun.reflect.GeneratedConstructorAccessor103.newInstance(Unknown Source) ~[na:na]
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.7.0_79]
	at java.lang.reflect.Constructor.newInstance(Constructor.java:526) ~[na:1.7.0_79]
	at com.mysql.jdbc.Util.handleNewInstance(Util.java:404) ~[mysql-connector-java-5.1.38.jar:5.1.38]
	at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:981) ~[mysql-connector-java-5.1.38.jar:5.1.38]
	at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3465) ~[mysql-connector-java-5.1.38.jar:5.1.38]
	at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3365) ~[mysql-connector-java-5.1.38.jar:5.1.38]
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3805) ~[mysql-connector-java-5.1.38.jar:5.1.38]
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478) ~[mysql-connector-java-5.1.38.jar:5.1.38]
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625) ~[mysql-connector-java-5.1.38.jar:5.1.38]
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551) ~[mysql-connector-java-5.1.38.jar:5.1.38]
	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861) ~[mysql-connector-java-5.1.38.jar:5.1.38]
	at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1962) ~[mysql-connector-java-5.1.38.jar:5.1.38]
	at com.alibaba.druid.pool.DruidPooledPreparedStatement.executeQuery(DruidPooledPreparedStatement.java:227) ~[druid-1.0.5.jar:1.0.5]
	at com.jfinal.plugin.activerecord.DbPro.query(DbPro.java:73) [jfinal-2.2.jar:na]
	at com.jfinal.plugin.activerecord.DbPro.query(DbPro.java:100) [jfinal-2.2.jar:na]
	at com.jfinal.plugin.activerecord.Db.query(Db.java:47) [jfinal-2.2.jar:na]
	...
	
Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
	at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2957) ~[mysql-connector-java-5.1.38.jar:5.1.38]
	at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3375) ~[mysql-connector-java-5.1.38.jar:5.1.38]
	... 55 common frames omitted


參考鏈接:

http://blog.csdn.net/pandajava/article/details/41946251

http://blog.csdn.net/shiqidide/article/details/7642531

https://stackoverflow.com/questions/2983248/com-mysql-jdbc-exceptions-jdbc4-communicationsexception-communications-link-fai



起因和現象:

項目運行後,莫名其妙就在log中看到這個報錯,但是數據也能獲取到,不影響日常使用,但是看到了總歸不爽。


看了下網上的原因:

MySQL服務器默認的“wait_timeout”是28800秒即8小時,意味着如果一個連接的空閒時間超過8個小時,MySQL將自動斷開該連接,而連接池卻認爲該連接還是有效的(因爲並未校驗連接的有效性),當應用申請使用該連接時,就會導致上面的報錯。
出現異常”The last packet sent successfully to the server was 0 milliseconds ago.“的大部分原因


是由於數據庫回收了連接,而系統的緩衝池不知道,繼續使用被回收的連接所致的。


解決方法:

1.JDBC的URL中加上屬性(舊版本可用,不推薦)

按照錯誤的提示,可以在JDBC URL中使用autoReconnect屬性,實際測試時使用了autoReconnect=true&failOverReadOnly=false,不過並未起作用,
使用的是5.1版本,可能真像網上所說的只對4之前的版本有效。


2.修改MYSQL的配置文件my.ini/my.cnf,添加超時等待參數的最長時間(推薦)

沒辦法,只能修改MySQL的參數了,wait_timeout最大爲31536000即1年,在my.cnf中加入:
[mysqld]
wait_timeout=86400 (8天)
interactive_timeout=7200
重啓生效,需要同時修改這兩個參數。

3.修改配置,讓緩衝池驗證鏈接是否有效

#SQL查詢,用來驗證從連接池取出的連接
dbcp.validationQuery=SELECT 1
#指明連接是否被空閒連接回收器(如果有)進行檢驗,如果檢測失敗,則連接將被從池中去除
dbcp.testWhileIdle=true
#在空閒連接回收器線程運行期間休眠的時間值,以毫秒爲單位,一般比minEvictableIdleTimeMillis小
dbcp.timeBetweenEvictionRunsMillis=300000
#在每次空閒連接回收器線程(如果有)運行時檢查的連接數量,最好和maxActive一致
dbcp.numTestsPerEvictionRun=50
#連接池中連接,在時間段內一直空閒,被逐出連接池的時間(1000*60*60),以毫秒爲單位
dbcp.minEvictableIdleTimeMillis=3600000


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章