DBCP2连接池频繁报错java.lang.IllegalStateException: Pool not open问题

问题现象:

服务频繁出现 java.lang.IllegalStateException: Pool not open 报错。        

问题原因:

连接池的实现中一般会通过定时任务对失效连接进行过期检测,并及时剔除。在dbcp2连接池中,该定时器任务实现类为:BaseGenericObjectPool.Evictor。

一般一个服务会因为连接不同的集群,不同的节点,从而需要创建多个连接池。每个连接池都会有一个对应的 Evictor进行过期连接检测、剔除。

commons-dbcp2:2.1.1包会依赖commons-pool2:2.4.3。该包中这部分功能的实现代码有bug,具体bug如下:

连接池创建时,定时任务启动代码为:

可以看到,这里创建了一个ScheduledThreadPoolExecutor线程池,并调用线程池的scheduleWithFixedDelay方法,开始调度该任务。

而该调度任务的取消逻辑如下:

可以看到,这里主要是通过调用TimerTask.cancel()方法进行调度取消,需要注意的是,该方法是不能取消调度的。只有由Timer定时任务机制进行管理的TimerTask,才能通过调用cancel方法进行取消。上面是由ScheduledThreadPoolExecutor线程池实现的定时任务管理,需要调用提交任务返回的Feature.cancel方法进行取消。

  

再apache的问题修复记录中也记录了该问题:

详见:Issue Navigator - ASF JIRA

一般场景下,当db节点发生变更等情况,导致连接池关闭时,由于该bug。会导致该定时任务不能释放,由此会引发频繁打印日志、内存泄露问题。

解决方案:

升级commons-dbcp2版本即可。升级到2.5.0。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值