弹性数据库连接池探活策略调研 (三)——DBCP | 京东云技术团队
前言
在之前的文章中,我们介绍了弹性数据库连接失效的背景,并探讨了 HikariCP、Druid 连接池探活策略的相关内容。在本文中,我们将会继续探讨另一个线上常用的连接池——DBCP,并为您介绍如何在使用 DBCP 时实现最佳实践的弹性数据库连接池探活策略。
DBCP
DBCP 有两个版本:1.x 和 2.x(也称为 DBCP2)。DBCP 2 基于 Commons Pool 2,相比 1.x 版本,在性能、JMX 支持和其他许多方面都有所提高。由于 DBCP 2.x 与 DBCP 1.x 不是二进制兼容,所以升级到 2.x 的用户应该知道 Java 包名称已经改变,以及 Maven 坐标。
首先我们先列出关于 DBCP 探活相关的参数:
DBCP 和与 Druid 的探活配置相比,尽管它们的许多参数名字和功能相似,但在细节和默认值上存在不同之处。例如,testWhileIdle 参数在 Druid 中用于判断是否在申请连接时开启探活,且需大于 timeBetweenEvictionRunsMillis 参数值。而在 DBCP 中,该参数在驱逐连接时进行判断,若开启,则直接进行验证,类似 Druid 中的 keepAlive 参数。两个连接池中,驱逐空闲连接的时间间隔都受到 timeBetweenEvictionRunsMillis 参数的控制。此外,testOnBorrow 参数的功能相同,但默认值有所不同。
另外在 DBCP 在驱逐线程中也受 numTestsPerEvictionRun 参数影响,这个参数是指每次驱逐线程运行时驱逐连接的个数,不会一次检查池内全部的连接。此外 DBCP 的 minEvictableIdleTimeMillis 跟 Druid 不同超时驱逐的连接数不受 minidle 控制。
下图是 DBCP1.4.0 的驱逐连接线程的源码:org.apache.commons.pool.impl.GenericObjectPool#evict
我们可以从源码中看到驱逐的连接个数从 getNumTests 获取,getNumTests 返回的是连接池的现有 size 和 numTestsPerEvictionRun 的最小值。驱逐过程的第一步先判断空闲时间是否超过 minEvictableIdleTimeMillis,没有的话再判断 softMinEvictableIdleTimeMillis 是否超时和现有的连接是否大于 minIdle,第三个 if 是判断 testWhileIdle 的配置为 true 时且上面没有回收该连接,在第四步的时候对此连接进行探活。
总结:DBCP 在各个版本中对探活变动不大,一般都是在驱逐连接数时可以使用 testWhileIdle 来进行探活,驱逐线程运行的间隔时间是 timeBetweenEvictionRunsMillis 参数的值,此外 numTestsPerEvictionRun 参数是每次驱逐线程的个数,因此我们只要使用这两个参数设置的可以在 10 分钟之内对池内所有连接(最大值为 maxActive/maxTotal)进行探活就能有效避免 JED 网关的失效连接。
总的来说,DBCP 在不同版本中对探活的实现方式变化不大。通常情况下,可以通过在驱逐连接时使用 testWhileIdle 参数来进行连接的探活。驱逐线程的运行间隔时间受 timeBetweenEvictionRunsMillis 参数的控制,而 numTestsPerEvictionRun 参数则决定了每次驱逐线程可以处理的连接数。建议 numTestsPerEvictionRun 配置的值和 maxActive/maxTotal 一致,并配置 timeBetweenEvictionRunsMillis 小于 10 分钟能够保证对所有连接进行探活,避免拿到网关失效的连接。
此外,应用使用 DBCP 时,默认开启 testOnBorrow 参数一般可以有效避免拿到失效的连接,而 Druid 默认不开启 testOnBorrow 参数。关于是否开启 testOnBorrow 参数,应用可以自行评估。虽然开启 testOnBorrow 参数会在每次拿到连接前进行连接验证,损耗一小部分性能,但是这样能够及时销毁无效连接并重建新连接,在遇到 JED 网关故障重启时能够有效避免应用报错。
JED 配置模版:
DBCP1.4
DBCP2.2.0
DBCP2.1.1
同 2.2.0
总结
本文以 JED 的网关超时报错为背景,对常见的数据库连接池进行了调研,并介绍了连接池探活相关的参数和探活逻辑。通过本文的内容,读者应该了解到不同连接池的探活内容,可以根据不同的参数设置连接池,有效避免应用拿到网关关闭的连接。本文提供了在 JED 数据库中的连接池配置模板,读者可以根据自己的应用需求进行调整。
作者:京东零售 王雷鑫
来源:京东云开发者社区 转载请注明来源
版权声明: 本文为 InfoQ 作者【京东科技开发者】的原创文章。
原文链接:【http://xie.infoq.cn/article/7ad6de30c17d2d9cac84e7d14】。文章转载请联系作者。
评论