弹性数据库连接池探活策略调研(三)——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探活相关的参数:
| 参数名称 | 说明 | 默认值 |
|---|---|---|
| initialSize | 初始化时建立物理连接的个数。 | 0 |
| minIdle | 最小空闲连接:连接池中容许保持空闲状态的最小连接数量,低于这个数量将创建新的连接,如果设置为0则不创建 | 0 |
| maxIdle | 最大空闲连接:连接池中容许保持空闲状态的最大连接数量,超过的空闲连接将被释放,如果设置为负数表示不限制 | 8 |
| maxActive/maxTotal | 最大活动连接:连接池在同一时间能够分配的最大活动连接的数量,超过这个值的请求进入等待队列, 如果设置为非正数则表示不限制(1.x版本 maxActive 2.x版本maxTotal) | 8 |
| testOnBorrow | 指明是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个 | true |
| testOnReturn | 指明是否在归还到池中前进行检验。 | false |
| testWhileIdle | 指明连接是否被空闲连接回收器进行检验。如果检测失败,则连接将被从池中去除.注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串 | false |
| timeBetweenEvictionRunsMillis | 驱逐连接的线程运行的时间间隔,以毫秒为单位. 如果设置为非正数,则不运行空闲连接回收器线程 | -1 |
| validationQuery | 用来检测连接是否有效的sql,要求是一个查询语句。 | select 1 |
| validationQueryTimeout | 单位:秒,检测连接是否有效的超时时间。底层调用jdbc Statement对象的void setQueryTimeout(int seconds)方法 | |
| minEvictableIdleTimeMillis | 连接在池中处于空闲状态的最小时间,超过这个时间会被驱逐驱逐。 | 30分钟 |
| softMinEvictableIdleTimeMillis | 这个参数与minEvictableIdleTimeMillis相比是这个参数受minIdle的限制,当到达这个值的时候只会驱逐大于minIdle的连接数 | -1 |
| numTestsPerEvictionRun | 在每次空闲连接回收器线程运行时检查的连接数量。 | 3 |
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数据库中的连接池配置模板,读者可以根据自己的应用需求进行调整。
作者:京东零售 王雷鑫
来源:京东云开发者社区 转载请注明来源
弹性数据库连接池探活策略调研(三)——DBCP的更多相关文章
- 转!数据库连接池概念、种类、配置(DBCP\C3P0\JndI与Tomact配置连接池)
数据库连接池概念.种类.配置(DBCP\C3P0\JndI与Tomact配置连接池) 一.DBCP 连接:DBCP 连接池是 Apache 软件基金组织下的一个开源连接池实现. 需要的 java 包c ...
- 主流数据库连接池性能比较 hikari druid c3p0 dbcp jdbc
背景 对现有的数据库连接池做调研对比,综合性能,可靠性,稳定性,扩展性等因素选出推荐出最优的数据库连接池 . NOTE: 本文所有测试均是MySQL库 测试结论 1:性能方面 hikariCP> ...
- 数据库连接池性能比对(hikari druid c3p0 dbcp jdbc)
https://blog.csdn.net/qq_31125793/article/details/51241943 背景 对现有的数据库连接池做调研对比,综合性能,可靠性,稳定性,扩展性等因素选出推 ...
- 数据库连接池,DBUtil的模板,dbcp,c3p0
数据库连接池,DBUtil的模板,Druid使用(重点) 一.DBUtil模板 public class DBUtilTest { public static Connection connectio ...
- springboot数据库连接池使用策略
springboot官方文档介绍数据库连接池的使用策略如下: Production database connections can also be auto-configured using a p ...
- Java线程池的拒绝策略
一.简介 jdk1.5 版本新增了JUC并发编程包,极大的简化了传统的多线程开发.前面文章中介绍了线程池的使用,链接地址:https://www.cnblogs.com/eric-fang/p/900 ...
- Druid数据库连接池就这么简单
前言 本章节主要讲解Druid数据库连接池,为什么要学Druid数据库连接池呢?? 我的知识储备数据库连接池有两种->C3P0,DBCP,可是现在看起来并不够用阿~当时学习C3P0的时候,觉得这 ...
- JAVA之JDBC数据库连接池总结篇
JDBC数据库连接池 一.JDBC数据库连接池的必要性 二.数据库连接池技术 三.多种开源的数据库连接池 3.1 C3P0数据库连接池 3.2 DBCP数据库连接池 3.3 Druid(德鲁伊)数据库 ...
- JDBC学习笔记(8)——数据库连接池(dbcp&C3P0)
JDBC数据库连接池的必要性 一.在使用开发基于数据库的web程序时,传统的模式基本是按一下步骤: 1)在主程序(如servlet/beans)中建立数据库连接 2)进行sql操作 3)断开数据库连接 ...
- 【转】JDBC学习笔记(8)——数据库连接池(dbcp&C3P0)
转自:http://www.cnblogs.com/ysw-go/ JDBC数据库连接池的必要性 一.在使用开发基于数据库的web程序时,传统的模式基本是按一下步骤: 1)在主程序(如servlet/ ...
随机推荐
- 如何编写一个健壮的 npm 包
无脑发布 npm 比如老王我,用npm init新建一个包,改把改把,然后来个npm publish,so easy ️! Too young too naive, baby ! 请容我讲述一些发布过 ...
- 使用默认pypi源出现连接超时
背景信息 安装 dataworks sdk 时报错,原因是连接默认的 pypi 仓库超时 pip install aliyun-python-sdk-dataworks-public==4.2.1 报 ...
- 龙芯下如何进行.net core程序开发部署
龙芯LoongArch64已经发布了对.NETCore的支持,相关工具链也已完成,目前支持.NETCore3.1..NET6..NET7版本.本文以.NETCore3.1在loongnix-serve ...
- 曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)
原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/ 译者:池中物王二狗(sheldon) 源码:github: ht ...
- 【TVM模型编译】1. onnx2relay.md
上一篇介绍了onnx模型在tvm中优化的总体流程. 在这一篇中,介绍onnx模型到relay模型的转换流程,主要涉及了以下几个方面: onnx算子到relay算子转换 relay算子实现 这一篇介绍o ...
- #mac安装Homebrew报错问题:curl: (7) Failed to connect to raw.githubusercontent.com port 443: Connection refused
我们在打开https://brew.sh/index_zh-cn官网的时候都会给你下面这段代码,粘贴复制就可以安装: /bin/bash -c "$(curl -fsSL https://r ...
- 快速上手 vercel,手把手教你白嫖部署上线你的个人项目
一.关于 vercel Vercel 是一个云服务平台,支持静态网站(纯静态页面,比如现在base utils 文档也是基于vercel)和动态网站的应用部署.预览和上线.如果你用过 GitHub P ...
- SpringBoot 拦截器 & 过滤器
拦截器 Java里的拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码,也可以在一个Action执行前阻止其执行,同时也提供了一种可以提取Ac ...
- Python 引用问题 - ImportError: attempted relative import with no known parent package
问题描述 近日在尝试引用其他文件的代码时,遇到了错误: ImportError: attempted relative import with no known parent package. 问题大 ...
- Java扩展Nginx之二:编译nginx-clojure源码
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 为什么要编译nginx-clojure源码 作为< ...