写点什么

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

  • 2023-09-06
    北京
  • 本文字数:1911 字

    阅读完需:约 6 分钟

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

调研背景:

数据库连接建立是比较昂贵的操作(至少对于 OLTP),不仅要建立 TCP 连接外还需要进行连接鉴权操作,所以客户端通常会把数据库连接保存到连接池中进行复用。连接池维护到弹性数据库(JED)的长连接,弹性数据库默认不会主动关闭客户端连接(除非报错),但一般客户端到弹性数据库之间还会有负载均衡代理,它们通常为了节约连接资源会在连接空闲 10 分钟后主动清理连接,释放无用的连接资源。这就导致一些用户的连接池探活参数配置不当,进而拿到是已经失效的连接。客户端就会报以下错误:



基于以上的背景我们根据 Java 应用常用的连接池的常用版本的连接池探活相关的功能进行了调研,并对每个版本提供了 JED 配置的模版。目前,常用的连接池版本如下:


HikariCP 3.2.0、 3.4.5、4.0.3


DRUID 1.1.10、1.1.9、1.0.9


DBCP 1.4 、2.2.0、2.1.1

HikariCP

我们第一个章节先来介绍一下 HikariCP 连接池探活相关的内容:


HikariCP 连接池会在需要分配连接对象给应用程序使用时,先检查连接对象的状态。为了检测连接是否可用,连接池会调用isConnectionAlive方法。如果连接对象是可用的,连接池会将连接对象分配给应用程序使用;如果连接对象不可用,连接池会创建一个新的连接对象,并将新的连接对象分配给应用程序使用。


所以 HikariCP 连接池的连接对象失效时,连接池只会在日志中输出警告信息,建议缩短连接对象的最大生存时间(`maxLifetime`)。但是,这并不会影响程序的正常执行,因为连接池会自动重新创建新的连接对象并分配给应用程序使用。因此,应用程序可以继续使用连接池中的连接对象,而不会受到失效连接的影响。



虽然使用 HikariCP 连接池时,如果不配置连接探活,应用程序在拿到失效的连接时不会报错,但是当应用程序需要执行 SQL 时,可能会遇到失效的连接,导致需要重新建立连接,增加了额外的性能开销。这样就没有充分发挥连接池的优势,因为连接池的主要目的是通过重复使用连接对象来提高应用程序的性能和可伸缩性。


为了最大化发挥连接池的价值,我们就一块来了解一下关于 HikariCP 探活相关的内容,看看如何利用相关的探活参数更高效地使用连接池。


以下是跟 HikariCP 探活通用的相关的参数:



HikariCP 连接池的探活代码如下。可以看到,在探活时,连接池会根据 isUseJdbc4Validation 属性的值来决定是否走 JDBC API 进行探活 isUseJdbc4Validation 属性的值是在初始化数据源时根据 connectionTestQuery 属性是否为空来赋值的。如果 connectionTestQuery 属性为空,isUseJdbc4Validation 属性的值为 true,连接池会走 JDBC API 进行探活。因此,在 JDBC 4.0 及以上版本中,不建议配置 connectionTestQuery 属性进行探活,因为这样会影响探活的效率。



在 HikariCP 较低的版本中,无法对连接进行保活,只能在每次获取连接时验证连接的有效性。而在 4.0.1 版本中,引入了 keepaliveTime 参数,可以定时的对连接进行探活。因此,为避免获取到已关闭的连接,在低版本中,只能将 maxLifetime 参数调整到少于 10 分钟,才能完全避免拿到网关已经关闭的连接。在 4.0.1 及以上版本中,可以使用 keepaliveTime 参数配合 connectionTestQuery 参数进行连接探活,从而在获取连接之前就进行探活。这样可以提高连接的可靠性和稳定性,避免应用程序遇到无效连接的情况。


配置 keepaliveTime 后我们可以看到每次到配置的时间就会打印出来探活日志



因此针对线上使用 HikariCP 的应用推荐使用 4.0.1 以上支持 keepaliveTime 的版本。

JED 配置模版:

HikariCP3.2.0

spring.datasource.hikari.minimumIdle=5spring.datasource.hikari.maximumPoolSize=10spring.datasource.hikari.maxLifetime=540000spring.datasource.hikari.idleTimeout=480000#JDBC4以上的版本不建议配置connectionTestQueryspring.datasource.hikari.connectionTestQuery=select 1
复制代码


低版本中主要保证 maxLifetime 低于 10 分钟能够完全避免拿到网关已经关闭的连接,但可能会造成频繁的创建销毁连接所以建议使用 4.0.1 以上支持 keepaliveTime 的版本。

HikariCP3.4.5

同 3.2.0 版本。

HikariCP4.0.3

spring.datasource.hikari.minimumIdle=5spring.datasource.hikari.maximumPoolSize=10spring.datasource.hikari.maxLifetime=1800000spring.datasource.hikari.idleTimeout=600000#JDBC4以上的版本不建议配置connectionTestQueryspring.datasource.hikari.connectionTestQuery=select 1spring.datasource.hikari.keepaliveTime=300000
复制代码


4.0.1 以上的版本中可以把 keepaliveTime 参数设置小于 10 分钟对连接进行探活,就能避免拿到被网关关闭的连接,maxLifetime 的时间就可以延长能避免频繁的创建销毁连接。


参考文档: https://github.com/brettwooldridge/HikariCP#readme


作者:京东零售 王雷鑫

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

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

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

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

评论

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