首页 > 数据库 >弹性数据库连接池探活策略调研(三)——DBCP

弹性数据库连接池探活策略调研(三)——DBCP

时间:2023-09-08 09:47:39浏览次数:36  
标签:驱逐 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,参数,连接,连接池,探活
From: https://www.cnblogs.com/jingdongkeji/p/17686668.html

相关文章

  • 弹性数据库连接池探活策略调研(二)——Druid | 京东云技术团队
    前言在上一篇文章中,我们介绍了弹性数据库连接失效的背景,并探讨了HikariCP连接池探活策略的相关内容。在本文中,我们将会继续探讨另一个线上常用的连接池——Druid,并为您介绍如何在使用Druid时实现最佳实践的弹性数据库连接池探活策略。DruidDruid的版本迭代更新比较快,同时探活配置的......
  • C++_手写数据库连接池
    C++_手写数据库连接池关键技术点MySQL数据库编程、单例模式、queue队列容器、C++11多线程编程、线程互斥、线程同步通信和unique_lock、基于CAS的原子整形、智能指针shared_ptr、lambda表达式、生产者-消费者线程模型连接池的主要功能点单例模式:因为连接池只需要一个实例......
  • 深入理解数据库连接池及其在后端性能优化中的作用
    在后端开发中,数据库连接池是一个至关重要的概念,它在保障系统性能、资源利用以及稳定性方面起着重要作用。本篇博客将深入探讨数据库连接池的工作原理,以及在Java应用中如何合理地配置和使用连接池来优化后端性能。什么是数据库连接池?数据库连接池是一个管理数据库连接的技术,它在应用......
  • XApool连接池报空指针错误解决
    atorg.enhydra.jdbc.pool.GenericPool.getFromPool(GenericPool.java:200)atorg.enhydra.jdbc.pool.GenericPool.checkOut(GenericPool.java:351)atorg.enhydra.jdbc.pool.StandardPoolDataSource.getConnection(StandardPoolDataSource.java:194)atorg.enhydra.jdb......
  • SpringBoot内嵌Tomcat连接池分析
    目录1Tomcat连接池1.1简介1.2架构图1.2.1JDK线程池架构图1.2.2Tomcat线程架构1.3核心参数1.3.1AcceptCount1.3.2MaxConnections1.3.3MinSpareThread/MaxThread1.3.4MaxKeepAliveRequests1.3.5ConnectionTimeout1.3.6KeepAliveTimeout1.4核心内部线程1.4.1Acceptor1.......
  • gRPC 客户端调用服务端需要连接池吗?
    发现的问题在微服务开发中,gRPC的应用绝对少不了,一般情况下,内部微服务交互,通常是使用RPC进行通信,如果是外部通信的话,会提供https接口文档对于gRPC的基本使用可以查看文章gRPC介绍对于gRPC,我们需要基本知道如下的一些知识点:gRPC的基本四种模式的应用场景请求响应......
  • C3P0连接池配置
    C3P0是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection和Statement池的DataSources对象。<c3p0-config><default-config><!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default:3--><propert......
  • 深入研究高性能数据库连接池的实现原理与优化策略
    在现代的后端应用开发中,数据库连接池是提高性能和可伸缩性的关键组件之一。本文将深入探讨数据库连接池的实现原理,涵盖Java和Python示例,并介绍一些常见的连接池优化策略。数据库连接池的作用数据库连接池是一种维护和管理数据库连接的技术,它通过预先创建一组数据库连接,并将这些连接......
  • 解密数据库连接池的奥秘与优化策略
    在后端开发中,数据库是应用程序的核心数据存储和管理部分。为了高效地处理数据库连接,提升应用性能,数据库连接池成为了不可或缺的技术。本文将深入探讨数据库连接池的工作原理,并介绍一些优化策略,帮助你更好地理解和使用数据库连接池。数据库连接池的背景与作用数据库连接是有代价的资......
  • 数据库连接池为什么要用threadlocal呢?不用会怎样?
    数据库连接池使用ThreadLocal的主要原因是为了保证每个线程都有其独立的数据库连接,这样可以避免多个线程之间的连接干扰,提高系统的稳定性和性能。为什么使用ThreadLocal?线程安全:ThreadLocal可以为每个线程提供一个独立的数据库连接,确保多个线程操作数据库时不会出现资源竞争的......