背景
项目基于Spring boot 链接数据库用的Druid连接池1.1.16版。通过nginx代理连接数据库。数据库配置
1 | show VARIABLES like '%timeout%' |
物理链接空闲1000秒后会进行回收。
druid连接池配置:
1 | timeBetweenEvictionRunsMillis: 10000 |
每隔10秒回进行判断空闲时间大于30秒的,或者总存活时间大于84秒的,是否需要回收。按照道理不会有问题,但是执行后会发现druid后台的逻辑链接打开次数
大于逻辑链接关闭次数。两者之差,正好等于物理连接打开次数-物理链接关闭次数-1。(-1是因为配置的最小链接数量)。通过后台日志查看到会报
1 | Communications link failure\n\nThe last packet successfully received from the server was 3 milliseconds ago. The last packet sent successfully to the server was 4 milliseconds ago.; nested exception is com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure\n\nThe last packet successfully received from the server was 3 milliseconds ago. The last packet sent successfully to the server was 4 milliseconds ago. |
看着很难受,也影响使用。
原因
druid通过MySqlValidConnectionChecker类进行链接健康检查。
1 | public class MySqlValidConnectionChecker{ |
检查链接是否存活。默认是用的internalPing方法。这个方法会一直返回true 当达到mysql的wait_timeout后。数据库将物理链接关闭,druid端还认为可用。
这就有问题了。
解决方法
使用validationQuery进行检查。
配置方法如下:
1 | 1. 增加yml配置 |