前言
在上一篇文章中,咱们介绍了弹性数据库连贯生效的背景,并探讨了 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。
作者:京东批发 王雷鑫
起源:京东云开发者社区 转载请注明起源