远程MySQL查询时间很长 Druid报skip not validate connection
情况描述
mysql从本地数据库迁移到云服务器上后,服务启动开始时没有问题,但是运行一段时间后经常遇到查询时间需要十几秒的问题,这个问题困扰了我许久,一直找不到原因。直到一天我看到一篇博文,才得知原因。
报错信息
服务启动后的开始一段时间一般不会有任何问题,但是过了一段时间后,查询时间长达数十秒,一开始我以为是连接池的问题,更换过连接池
一开始使用的是Hikari连接池,这个连接池是SpringBoot默认的,他的错误信息就是说jdbc连接超时异常,然后过一段时间使用其他连接然后查询成功,
这个过程有时长达数十秒。
后来换了druid连接池,还是有同样的问题
druid的一直打印debug级别的日志
Enabling session validation scheduler...
skip not validate connection...
等等
原因分析
从一篇博文中得知别人遇到和我一样的问题,他的原因描述是
数据库服务器的防火墙会自动中断一段时间未活动的TCP连接,相当于中断了数据库物理连接,Druid连接池中维护的数据库逻辑连接尝试与数据库服务器进行被服务器单方面中断的连接进行TCP通信,会失败(Druid把异常捕获了。。只返回false,然后Druid再新开一个TCP连接),重要的是这个失败的过程耗时很长(我们环境反应的是18秒左右的时间)
博文地址: https://www.oschina.net/question/1377217_2135711
但是遗憾的是并没有给出有效的解决方法。
解决方案
后来问了无所不知的群友,我这才得知了三个名词概念
Mysql:net_read_timeout 在终止读之前,从一个连接获得数据而等待的时间秒数;当服务正在从客户端读取数据时,net_read_timeout控制何时超时
druid: timeBetweenEvictionRunsMillis 空闲时间大于这个值时就回判断连接是否还有效
druid: minEvictableIdleTimeMillis 连接空闲时间大于该值并且池中空闲连接大于minIdle则关闭该连接
Druid的默认timeBetweenEvictionRunsMillis为60s,而我的mysql的net_read_tiemout为30
群里大佬告诉我,read timeout 同 druid 保持一致或者 MySQL 的略长于 druid 的闲置时间,
将timeBetweenEvictionRunsMillis 和minEvictableIdleTimeMillis配置小点
这样就能再连接失效后,关闭失效的连接,避免卡在死连接上。