最近再做一个采用spring-boot2.0+阿里druid+redis+mysql的项目,再部署上线之后,测试过程中遇到如下两种情况的报错:
Could not retrieve transaction read-only status from server; nested exception is java.sql.SQLException: Could not retrieve transaction read-only status from server] with root cause
java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.和
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.
经过排查发现是因为MySQL数据库连接池失效导致的问题。
MySQL默认的数据库连接池保存时间为28800秒,即超过8小时就会出现连接池失效,就会导致以上问题。
可以通过以下方式解决这个问题:
1、/etc/my.cnf配置[mysqld]中添加如下 [mysqld] interactive_timeout=2147483 wait_timeout=2147483 interactive_timeout和wait_timeout 在这里设置的都是秒,另外这个最长时间是24.5天即:2147483秒,设置过大也不能超过这个值,设置好需要对MySQL进行重启。另外如果项目已经上线为了避免重启MySQL数据库可以通过以下方式修改:
mysql> set global wait_timeout=10;
mysql> show global variables like 'wait_timeout'; 该设置立即生效不用重启MySQL。
2、修改MySQL中的testOnBorrow为true,指明是否再从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试读取另一个,这样显然会增加一定的开销,网上一般不建议在生产环境采用这种方法,但是具体影响多少的性能,目前没有测试结果。
先写这么多后面再补。