Java Hikari 连接池,连接超时被关闭

2020-07-10 16:35:01 +08:00
 Cinleoi

最近基于 WebMagic 在做一个爬虫项目。在一个接口中开启爬虫爬一个网站,用的阻塞模式。

之前都没有任何问题,但是最近新的一个网站,因为爬取的时间在 30 分钟左右,等爬完了,做数据持久化操作的时候,就抛出了连接超时被关闭的异常。

希望有遇到过这种情况的大神朋友能给点解决思路。

异常如下: c.z.hikari.pool.ProxyConnection - [153] - DatebookHikariCP - Connection com.mysql.cj.jdbc.ConnectionImpl@215164ec marked as broken because of SQLSTATE(08S01), ErrorCode(0) com.mysql.cj.jdbc.exceptions.CommunicationsException: The last packet successfully received from the server was 1,946,875 milliseconds ago. The last packet sent successfully to the server was 1,946,924 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.

在数据库 url 中添加‘autoReconnect=true’参数,以及配置 hikari 的心跳检测都依然抛出这个错误。感觉很不合理,因为 mysql 数据库默认的超时时间是 8 小时。

下面是我 hikari 的配置 hikari: auto-commit: true connection-test-query: SELECT 1 connection-timeout: 30000 idle-timeout: 30000 max-lifetime: 1800000 maximum-pool-size: 15 minimum-idle: 5

5594 次点击
所在节点    Java
14 条回复
hantsy
2020-07-10 21:05:21 +08:00
The last packet sent successfully to the server was 1,946,924 milliseconds ago. is longer than the server configured value of 'wait_timeout'.You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.

这已经好直白了。

程序本身肯定有问题。
zjp
2020-07-10 22:34:32 +08:00
https://blog.shadowland.cn/java/mysql/2017/09/23/cjcommunicationsexception/
autoReconnect 是不推荐的做法,需要的是 testOnBorrow 或者 testWhileIdle 。
The last packet sent successfully to the server was 1,946,924 milliseconds ago. 说明不是 8 小时自动超时,需要检查下是否是数据库主动释放了连接
seliote
2020-07-10 22:47:53 +08:00
## Maximum lifetime, if not use begin this it will be release
## this value should lower than `show variables like 'wait_timeout';`
database.max-lifetime=60000
Cinleoi
2020-07-11 10:13:33 +08:00
@hantsy 我参考了报错提示以及 Stack Overflow 上很多的解决方案,都无作用,现在还没定位的就是连接池把连接断开了还是 mysql 断开的
Cinleoi
2020-07-11 10:15:46 +08:00
@zjp testOnBorrow 、testWhileldle hikari 没有对应的属性,链接文章推荐的解决方法是换 Tomcat JDBC 连接池,但是目前项目换连接池不太合适
Cinleoi
2020-07-11 10:16:33 +08:00
@seliote 设了 60000 毫秒也不管用。哭了
hantsy
2020-07-11 10:24:54 +08:00
我相信不是连接池的问题,而是你的程序中有线程问题。
hantsy
2020-07-11 10:28:15 +08:00
@Cinleoi Tomcat 现在切换到 Dbcp2 ( Apache Commons Pool2 )了吗?

如果切换到 Tomcat 的连接池,我建议用 War 部署,使用 Tomcat 本身去管理 DataSource (应用服务器管理服务器资源效率高得多), 程序中用 JDNI 去连接 DataSource 。
Cinleoi
2020-07-11 12:04:06 +08:00
@hantsy 暂时没换,还是用的 Hikari 。程序中执行事务操作的代码是在主线程,但是是要等待阻塞的爬虫线程执行完,我想连接应该就是这里导致了等待空闲时间过长,导致被回收了,但是也没有超过 mysql 的 8 小时,着实想不通了
Jrue0011
2020-07-11 13:28:12 +08:00
hikaricp 推荐 maxlifetime 比数据库的连接超时设置短个几秒,或者把 maxlifetime 设置成 0(无限)试试?
Cinleoi
2020-07-11 16:45:54 +08:00
@Jrue0011 试过了,也是不行的。所以就很离谱,那就说明不是 hikari 回收的连接,mysql 的是 8 小时,也远远没达到回收时间。
running17
2020-07-11 19:36:12 +08:00
ma 一下,之前也遇到这个问题,没能解决,后面就换了 druid
6IbA2bj5ip3tK49j
2020-07-12 00:30:44 +08:00
testOnBorrow 应该可以解决这个问题。
也有一个很 tricky 的解决方案:写个定时任务时不时查询一下数据库。
ToddTong
2020-12-09 14:00:23 +08:00
@Cinleoi 请问最后是怎么解决的呢,我这边使用 hikari 连接池也会遇到类似的问题,耗时的定时任务在执行的过程中也会出现 Communications link failure 的问题

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/688926

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX