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

转载,原文地址:https://blog.csdn.net/tuntun1120/article/details/78866991

转载: https://blog.csdn.net/zl386119974/article/details/84875089

数据库连接报错

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 这个时间配置的是1小时,而数据库设置的是30分钟,则会出现问题

 

其他解决方法



mysql﹥ show global variables like 'wait_timeout'; 

+---------------+---------+ 

| Variable_name | Value | 

+---------------+---------+ 

| wait_timeout | 28800 | 

+---------------+---------+ 

1 row in set (0.00 sec) 


28800 seconds,也就是8小时。 

如果在wait_timeout秒期间内,数据库连接(java.sql.Connection)一直处于等待状态,mysql5就将该连接关闭。这时,你的Java应用的连接池仍然合法地持有该连接的引用。当用该连接来进行数据库操作时,就碰到上述错误。这解释了为什么我的程序第二天不能登录 的问题。 

你可能会想到在tomcat的数据源配置中有没有办法解决?的确,在jdbc连接url的配置中,你可以附上“autoReconnect=true”,但这仅对mysql5以前的版本起作用。增加“validation query”似乎也无济于事。 

本人觉得最简单的办法,就是对症下药:既然问题是由mysql5的全局变量wait_timeout的缺省值太小引起的,我们将其改大就好了。 

查看mysql5的手册,发现对wait_timeout的最大值分别是24天/365天(windows/linux)。以windows为 例,假设我们要将其设为21天,我们只要修改mysql5的配置文件“my.ini”(mysql5 installation dir),增加一行:wait_timeout=1814400 

需要重新启动mysql5。 

linux系统配置文件:/etc/my.cnf 

测试显示问题解决了。 


也可以直接设置 

mysql修改wait_timeout 

  mysql mysql> show global variables like 'wait_timeout'; 

  其默认值为8小时 

  mysql的一个connection空闲时间超过8小时,mysql会自动断开该连接。 

  1.修改配置 

  vi /etc/my.cnf 

  [mysqld] wait_timeout=10 

  # /etc/init.d/mysql restart 

  2.直接用sql命令行修改 mysql> set global wait_timeout=604800; 

除了wait_timeout,还有一个'interactive_timeout' 

同样可以执行SHOW GLOBAL VARIABLES LIKE 'interactive_timeout'来查询 
执行set global interactive_timeout=604800;来设置 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值