写点什么

弹性数据库连接池探活策略调研 (三)——DBCP | 京东云技术团队

  • 2023-09-08
    北京
  • 本文字数:1834 字

    阅读完需:约 6 分钟

弹性数据库连接池探活策略调研(三)——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

<propertyname="minIdle"value="5"/> <propertyname="maxActive"value="10"/> <propertyname="testWhileIdle"value="true"/>    <propertyname="validationQuery"value="SELECT 1"/>    <propertyname="timeBetweenEvictionRunsMillis"value="300000"/>    <propertyname="numTestsPerEvictionRun"value="10"/>   
复制代码

DBCP2.2.0

<propertyname="minIdle"value="5"/> <propertyname="maxTotal"value="10"/> <propertyname="testWhileIdle"value="true"/>    <propertyname="validationQuery"value="SELECT 1"/>    <propertyname="timeBetweenEvictionRunsMillis"value="300000"/>    <propertyname="numTestsPerEvictionRun"value="10"/>   
复制代码

DBCP2.1.1

同 2.2.0

总结

本文以 JED 的网关超时报错为背景,对常见的数据库连接池进行了调研,并介绍了连接池探活相关的参数和探活逻辑。通过本文的内容,读者应该了解到不同连接池的探活内容,可以根据不同的参数设置连接池,有效避免应用拿到网关关闭的连接。本文提供了在 JED 数据库中的连接池配置模板,读者可以根据自己的应用需求进行调整。


作者:京东零售 王雷鑫

来源:京东云开发者社区 转载请注明来源

发布于: 刚刚阅读数: 3
用户头像

拥抱技术,与开发者携手创造未来! 2018-11-20 加入

我们将持续为人工智能、大数据、云计算、物联网等相关领域的开发者,提供技术干货、行业技术内容、技术落地实践等文章内容。京东云开发者社区官方网站【https://developer.jdcloud.com/】,欢迎大家来玩

评论

发布
暂无评论
弹性数据库连接池探活策略调研(三)——DBCP | 京东云技术团队_数据库_京东科技开发者_InfoQ写作社区