mysql-CommunicationsException: Communications link failure

本文详细阐述了Mysql连接超时问题的原因,包括wait_timeout设置、连接回收与Druid连接池的关系。提供了两种解决方案:一是延长mysql wait_timeout,二是调整数据库连接池配置以检测并避免使用回收的连接。同时给出了c3p0配置示例和相关参考链接。
摘要由CSDN通过智能技术生成


问题

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

The last packet sent successfully to the server was 0 milliseconds ago. 
The driver has not received any packets from the server.
Communications link failure
The last packet successfully received from the server was 510,815 milliseconds ago.  The last packet sent successfully to the server was 0 milliseconds ago.

具体解释是这样的:Mysql服务器默认的“wait_timeout”是8小时【也就是默认的值默认是28800秒】,也就是说一个connection空闲超过8个小时,Mysql将自动断开该connection,通俗的讲就是一个连接在8小时内没有活动,就会自动断开该连接。而应用连接池却认为该连接还是有效的(因为并未校验连接的有效性),当应用申请使用该连接时,就会导致上面的报错。

解决方案

原因:由于数据库回收了连接,而系统的缓冲池不知道,继续使用被回收的连接所致的。
原因分析:

MySQL连接时,服务器默认的“wait_timeout”是8小时,也就是说一个connection空闲超过8个小时,Mysql将自动断开该connection。connections如果空闲超过8小时,Mysql将其断开,而Druid连接池并不知道该connection已经失效,如果这时有Client请求connection,Druid将该失效的Connection提供给Client,将会造成异常。

第一种解决办法

将mysql回收空闲连接的时间变长,mysql默认是8小时,可以在mysql目录下的my.ini中增加下面配置,将时间改为1天。
 [mysqld]
wait_timeout=86400

wait timeout的值可以设定,但最多只能是2147483,不能再大了。也就是约24.85天
所以即使你MySQL通过my.ini 在
#The TCP/IP Port the MySQL Server will listen on
port=3306下面添加
#this is myown dinifition for mysql connection timeout
wait_timeout=31536000
interactive_timeout=31536000
无论超过最大限度多大的数值,只能被MySQL解析为2147483

第二种解决办法

可以通过配置,让缓冲池去测试连接是否被回收,如果被回收,则不继续使用,以dbcp为例

知识点:

     	 #配置初始化大小、最小、最大
	    maxActive: 20   # 连接池最大活跃连接数
	    initialSize: 1      # 初始化连接池的连接数
	    minIdle: 3         # 空闲链接保持数量
	    maxWait: 60000    # 最大的响应等待时间,单位毫秒
	    numTestsPerEvictionRun=50	#在每次空闲连接回收器线程(如果有)运行时检查的连接数量,最好和maxActive一致
	    time-between-eviction-runs-millis: 60000   #在空闲连接回收器线程运行期间休眠的时间值,以毫秒为单位,一般比minEvictableIdleTimeMillis小
	    minEvictableIdleTimeMillis: 300000 #连接池中连接,在时间段内一直空闲,被逐出连接池的时间(1000*60*60),以毫秒为单位
	    validationQuery: SELECT 1 FROM DUAL #SQL查询,用来验证从连接池取出的连接
	    test-while-idle: true   #指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除.注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串
	    test-on-borrow: false   # 指明是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个.注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串
	    test-on-return: false    # 指明是否在归还到池中前进行检验 注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串

解决方案:

1、按照错误的提示,可以在JDBC URL中使用autoReconnect属性,实际测试时使用了autoReconnect=true&failOverReadOnly=false,不过并未起作用,使用的是5.1版本,可能真像网上所说的只对4之前的版本有效。

2、增大mysql的wait_timeout属性值;(起不到实质性作用)

show variables like ‘%timeout’;

3、最好的解决方法,如果使用了c3p0连接池,可以配置idleConnectionTestPeriod 属性,每多少秒检查所有连接池中的空闲连接,把该值设置的小于mysql的wait_timeout值即可。

参考

参考
https://www.cnblogs.com/outpointexception/p/11107221.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值