弹性数据库连接池探活策略调研(二)——Druid
前言
在上一篇文章中,我们介绍了弹性数据库连接失效的背景,并探讨了HikariCP连接池探活策略的相关内容。在本文中,我们将会继续探讨另一个线上常用的连接池——Druid,并为您介绍如何在使用Druid时实现最佳实践的弹性数据库连接池探活策略。
Druid
Druid的版本迭代更新比较快,同时探活配置的参数也比较多,这导致即使是相同的参数在不同的版本中达到的效果也可能不一样。但与探活相关的逻辑实现只存在源码里的两个函数里, 我们先列举一下跟Druid探活相关的参数,在具体看一下源码的实现对这些参数的使用。日后我们在开发中遇到配置探活不生效的情况下,可以看一下对应版本源码来判断自己的探活是否配置正确。
下面是与Druid探活相关的参数:
| 参数名称 | 说明 | 默认值 |
|---|---|---|
| initialSize | 初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时。 | 0 |
| minIdle | 最小连接池数量。 | 0 |
| maxActive | 最大连接池数量。 | 8 |
| testOnBorrow | 申请连接时执行validationQuery配置的SQL检测连接是否有效,做了这个配置会降低性能。 | false |
| testOnReturn | 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 | false |
| testWhileIdle | 建议配置为true,不影响性能,并且保证安全性。在连接池中申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 | 大多数版本为True |
| timeBetweenEvictionRunsMillis | 1) Destroy线程会检测连接的间隔时间,每隔这个值的时间就会执行一次DestroyTask。 2) testWhileIdle的判断依据,详细看testWhileIdle属性的说明。 | 大多数版本是1分钟 |
| keepAlive | 连接池中的minIdle数量以内的连接,空闲时间超过minEvictableIdleTimeMillis,则会执行探活操作此参数在1.0.28以上的版本才支持 详细说明参考官方文档。 | false |
| keepAliveBetweenTimeMillis | 配合keepAlive使用在低版本不支持,如果空闲时间小于timeBetweenEvictionRunsMillis但大于keepAliveBetweenTimeMillis扔执行探活操作 | 大多数版本是2分钟 |
| validationQuery | 用来检测连接是否有效的sql,要求是一个查询语句。 | select 1 |
| validationQueryTimeout | 单位:秒,检测连接是否有效的超时时间。底层调用jdbc Statement对象的void setQueryTimeout(int seconds)方法 | |
| minEvictableIdleTimeMillis | 连接空闲时间大于该值时关闭空闲连接大于minIdle的连接,类似hikaricp的idleTimeout | 30分钟 |
| maxEvictableIdleTimeMillis | 连接空闲时间大于该值时不管minIdle都关闭该连接,类似hikaricp的maxlifetime(低版本不支持) | 7小时 |
Druid的探活主要有以下两个函数来实现:
- com.alibaba.druid.pool.DruidDataSource#getConnectionDirect
getConnectionDirect是每次从连接池中取连接时会被调用的函数。我们从下面的代码中可以看出,如果testOnBorrow为true,则每次获取连接之前都会检测连接是否有效。如果testOnBorrow为false且testWhileIdle为true,则需要判断连接的空闲时间是否超过timeBetweenEvictionRunsMillis设置的值,如果超过则进行探活检测。失效的连接会被丢弃,并且会补充到连接池的minIdle数量。timeBetweenEvictionRunsMillis在大多数版本中的默认值为1分钟。只要这个值设置的时间小于十分钟,并且保证testWhileIdle开启,就能保证拿不到网关关闭的失效连接。
在不支持keepalive的低版本中,只能依靠testOnBorrow或testWhileIdle来进行探活。建议配置testWhileIdle来进行探活。在高并发的场景下,这种方式的性能消耗会更小一些。
- com.alibaba.druid.pool.DruidDataSource#shrink(boolean, boolean)
在下面的代码中我们可以看出,shrink方法是在DestroyTask线程的run方法中调用的,用于销毁连接池中的连接。如果timeBetweenEvictionRunsMillis大于0,则每隔这个时间间隔就会调用destroyTask.run(boolean, boolean)方法,即执行shrink方法。
从上面的代码中可以看出,shrink方法会使用keepAlive参数。需要注意的是,在不同版本的Druid中,keepAlive参数的支持和实现逻辑可能不同。官方建议在使用keepAlive参数时,应该使用1.1.21以上的版本。尽管官方文档中说明了空闲时间超过minEvictableIdleTimeMillis,就会执行探活操作,但是在高版本中,这个探活操作的执行时间也受到了keepAliveBetweenTimeMillis参数的影响。因此,在高版本中,如果想要正确地使用keepAlive参数,就需要了解其在具体版本中的实现逻辑。
下面代码是1.1.10和1.1.21版本中关于shrink方法的源码对比:
首先看一下1.1.10版本的源码,它首先会判断连接空闲时间是否大于minEvictableIdleTimeMillis,如果是,则接下来进行第二步的判断:是否是多于minIdle的空闲连接。如果是,就将这些连接加入到驱逐连接的数组中,以便进行后续的驱逐操作。如果不是,就再次判断连接空闲时间是否大于maxEvictableIdleTimeMillis,如果是,则将这些连接加入到驱逐连接的数组中。如果也不是,则进行最后的判断:是否开启了keepAlive配置。如果开启了,就将这些连接加入到保活连接数组中,以进行后续的探活操作。
在1.1.21版本中,shrink方法的总体逻辑与1.1.10版本类似,但是新增了一个名为keepAliveBetweenTimeMillis的参数。这个参数决定了使用keepAlive进行探活的时间间隔,其默认值为2分钟,keepalive开启且空闲时间大于这个值会进行探活。
另一个不同点是,在进行探活操作时,1.1.10版本仅会关闭无效的连接,但1.1.21版本则更进一步,除了关闭无效连接外,还会自动添加连接以达到minIdle的最小连接数。
1.1.10 1.1.21
总结,druid的探活参数在1.0.28版本之前没有定时的探活功能只能在每次拿到连接前进行检测是否有效,建议配置testWhileIdle为true在高并发情况下不会太影响性能,如果对可用性要求高的可以开启testOnBorrow,以在每次获取连接时检测连接的有效性。在高版本中可以用keepAlive参数对连接进行保活。针对线上使用Druid连接池的应用建议使用支持keepAlive的1.1.21或者更高版本。
JED配置模版:
Druid1.1.10
<propertyname="testWhileIdle"value="true"/>
<propertyname="validationQuery"value="SELECT 1"/>
<propertyname="timeBetweenEvictionRunsMillis"value="30000"/>
<propertyname="minEvictableIdleTimeMillis"value="300000"/>
<propertyname="keepAlive"value=true/>
此版本支持keepAlive可以配置minEvictableIdleTimeMillis时间小于10分钟,能够高效的进行探活防止网关关闭连接。
Druid1.1.9
同1.1.10
Druid1.0.9
<propertyname="testWhileIdle"value="true"/>
<propertyname="validationQuery"value="SELECT 1"/>
<propertyname="timeBetweenEvictionRunsMillis"value="30000"/>
<propertyname="minEvictableIdleTimeMillis"value="300000"/>
此版本不支持keepAlive只能在获取连接对象的时候检测,对可用性高的也可以开启testOnBorrow。
作者:京东零售 王雷鑫
来源:京东云开发者社区 转载请注明来源
弹性数据库连接池探活策略调研(二)——Druid的更多相关文章
- java连数据库和数据库连接池踩坑日记(二)-------数据库连接池c3p0
关于数据库连接池,我觉得有些沮丧,因为最后被毙掉了说不用考虑多线程的问题…… 数据库连接池的推荐:https://www.cnblogs.com/nuccch/p/8120349.html 我最终选择 ...
- 主流Java数据库连接池分析(C3P0,DBCP,TomcatPool,BoneCP,Druid)
主流数据库连接池 常用的主流开源数据库连接池有C3P0.DBCP.Tomcat Jdbc Pool.BoneCP.Druid等 C3p0: 开源的JDBC连接池,实现了数据源和JNDI绑定,支持JDB ...
- springboot数据库连接池使用策略
springboot官方文档介绍数据库连接池的使用策略如下: Production database connections can also be auto-configured using a p ...
- 数据库连接池,DBUtil的模板,dbcp,c3p0
数据库连接池,DBUtil的模板,Druid使用(重点) 一.DBUtil模板 public class DBUtilTest { public static Connection connectio ...
- spring boot:配置druid数据库连接池(开启sql防火墙/使用log4j2做异步日志/spring boot 2.3.2)
一,druid数据库连接池的功能? 1,Druid是阿里巴巴开发的号称为监控而生的数据库连接池 它的优点包括: 可以监控数据库访问性能 SQL执行日志 SQL防火墙 2,druid的官方站: http ...
- SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
作为后台服务开发,在日常工作中我们天天都在跟数据库打交道,一直在进行各种CRUD操作,都会使用到数据库连接池.按照发展历程,业界知名的数据库连接池有以下几种:c3p0.DBCP.Tomcat JDBC ...
- 数据库连接池--druid
数据库连接池常用的有:dbcp,c3p0,druid 代码仓库(https://github.com/) package com.huawei.test; import java.sql.Connec ...
- 数据库连接池Druid的介绍,配置分析对比总结
Druid的简介 Druid首先是一个数据库连接池.Druid是目前最好的数据库连接池,在功能.性能.扩展性方面,都超过其他数据库连接池,包括DBCP.C3P0.BoneCP.Proxool.JBos ...
- C3P0和Druid数据库连接池
目录 C3P0连接池 步骤: C3P0初始化: 创建C3P0工具类: 创建C3P0测试类: Druid连接池(由阿里巴巴提供的数据库连接池实现技术) 步骤: Druid初始化: 创建Druid工具类: ...
- [数据库连接池二]Java数据库连接池--C3P0和JDNI.
前言:上一篇文章中讲了DBCP的用法以及实现原理, 这一篇再来说下C3P0和JDNI的用法. 1.1.C3P0数据源 C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规 ...
随机推荐
- Linux 调用约定
函数调用约定是对函数调用时如何传递参数的一种约定.关于它的约定有许多种,下面我们分 别从内核接口和用户接口两方面介绍32位和64位Linux的调用约定. 一.内核接口 x86-32系统调用约定 ...
- [Kotlin Tutorials 21] 协程的取消
协程的取消 本文讨论协程的取消, 以及实现时可能会碰到的几个问题. 本文属于合辑: https://github.com/mengdd/KotlinTutorials 协程的取消 取消的意义: 避免资 ...
- STL-array(ACM)
1.C++ 11 出现的, C++98没有 2.可以作为数组元素 pair<array<int, 3>, int>pair<int a[3], int > 不能这样 ...
- 这就是艺术,优雅的二维码生成器「GitHub 热点速览」
平时如果没有需要一般那团黑乎乎的二维码,估计路过的人看见第一眼就不会再看第二眼.但是假若,它是个帅哥靓妹,估计就不同了,更别提像是艺术画一样,将编码图案融入到画里的二维码生成器 qrbtf 作者的新作 ...
- 曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)
原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/ 译者:池中物王二狗(sheldon) 源码:github: ht ...
- 【HMS Core】【In-App Purchases】应用内支付热门FAQ合集
近期收到很多开发者关于应用内支付服务的相关问题,主要集中在以下几个方面,今天和大家分享一下,希望给大家的开发集成带来帮助. [问题描述1] 近期,很多开发者收到关于"全面限制HTTP类型回 ...
- C#/.Net的多播委托到底是啥?彻底剖析下
前言 委托在.Net里面被托管代码封装了之后,看起来似乎有些复杂.但是实际上委托即是函数指针,而多播委托,即是函数指针链.本篇来只涉及底层的逻辑,慎入. 概括 1.示例代码 public delega ...
- 行行AI人才直播第6期:当AIGC时代降临,当代青年如何把握新时代机遇
AIGC时代的到来,给我们带来了无限的想象空间和创造力.AIGC不仅可以提高内容生产的效率和质量,还可以创造出人类无法想象的新颖和有价值的内容,为数字文化产业.产业互联网.社会价值等领域带来变革性的影 ...
- Spring容器获取Bean的9种方式
1 前言 随着SpringBoot的普及,Spring的使用也越来越广,在某些场景下,我们无法通过注解或配置的形式直接获取到某个Bean.比如,在某一些工具类.设计模式实现中需要使用到Spring容器 ...
- AI重塑千行百业,华为云发布盘古大模型3.0和昇腾AI云服务
[中国,东莞,2023年7月7日]华为开发者大会2023(Cloud)7月7日在中国东莞正式揭开帷幕,并同时在全球10余个国家.中国30多个城市设有分会场,邀请全球开发者共聚一堂,就AI浪潮之下的产业 ...