数据库故障后的 Hikari CP (Spring Boot) 连接恢复问题
Posted
技术标签:
【中文标题】数据库故障后的 Hikari CP (Spring Boot) 连接恢复问题【英文标题】:Hikari CP (Spring Boot) Connection Recovery Problem After DB Failure 【发布时间】:2021-12-02 13:49:57 【问题描述】:我们在 Spring Boot (2.2.4) 和 Hikari CP (3.4.2) 上使用 PostgreSQL 构建了多个微服务。
最近我们遇到了大约 30 秒的数据库故障。连接丢失后,一些容器无法恢复连接,而其他具有完全相同配置和应用程序的容器就可以了。不幸的是,我们没有在错误发生时指示池大小(空闲活动等待)的日志。
当连接丢失时,我们在所有容器上都收到了一些损坏的管道和连接丢失错误。数据库恢复后,我们仅在某些 (2/18) 无法恢复的容器上遇到以下异常。
堆栈跟踪:
org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:402) ... 20 moreCaused by:
java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30000ms. at
com.zaxxer.hikari.pool.HikariPool.createTimeoutException(HikariPool.java:689) at
com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:196) at
com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:161) at
com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:128) at
org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) at
org.hibernate.internal.NonContextualJdbcConnectionAccess.obtainConnection(NonContextualJdbcConnectionAccess.java:38) at
org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:104)
... 30 moreCaused by:org.postgresql.util.PSQLException: This connection has been closed. at
org.postgresql.jdbc.PgConnection.checkClosed(PgConnection.java:857) at
org.postgresql.jdbc.PgConnection.setNetworkTimeout(PgConnection.java:1639) at
com.zaxxer.hikari.pool.PoolBase.setNetworkTimeout(PoolBase.java:556) at
com.zaxxer.hikari.pool.PoolBase.isConnectionAlive(PoolBase.java:169) at
com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:185) ... 35 more
我们已经看到了类似(在同一系统上)的情况和测试,其中数据库故障转移和连接在 Hikari 上恢复而没有任何问题。但在这种情况下,其中一个容器在 1 小时后自行恢复,其他容器在重启后恢复。
据我们所知,Hikari 不会返回池中断开的连接,而是在标记为断开或关闭后将它们从池中逐出。任何想法可能发生在这些容器上而其他容器(完全相同的图像和配置)都很好。
PS:我们无法重现该问题。
Hikari 配置:
allowPoolSuspension.............假 connectionInitSql................无 connectionTestQuery.............无 连接超时......................30000 空闲超时.....................600000 初始化失败超时.......1 隔离内部查询........错误 泄漏检测阈值............0 最长寿命.....................1800000 最大池大小..................15 最小空闲.....................15 验证超时......................5000
【问题讨论】:
【参考方案1】:您可以配置如下:
connectionTestQuery=select 1
这样 Hikari 会在将其处理给 Hibernate 之前测试连接是否仍然存在。
【讨论】:
嗨,从 Hikari 文档来看,它适用于旧版驱动程序,而我们并非如此。 ?connectionTestQuery 如果您的驱动程序支持 JDBC4,我们强烈建议不要设置此属性。这适用于不支持 JDBC4 Connection.isValid() API 的“旧版”驱动程序。这是将在池中为您提供连接之前执行的查询,以验证与数据库的连接是否仍然存在。同样,尝试在没有此属性的情况下运行池,如果您的驱动程序不符合 JDBC4,HikariCP 将记录错误以通知您。默认值:无 有趣,谢谢。我们在 mysql 上遇到了类似的问题,添加connectionTestQuery
帮助很大,所以现在我不确定发生了什么以上是关于数据库故障后的 Hikari CP (Spring Boot) 连接恢复问题的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring(4) 上下文中为 HSQL 配置 Hikari CP?