【问题标题】:Hikari CP (Spring Boot) Connection Recovery Problem After DB Failure数据库故障后的 Hikari CP (Spring Boot) 连接恢复问题
【发布时间】: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

【问题讨论】:

    标签: spring-boot hibernate hikaricp


    【解决方案1】:

    您可以配置如下:

    connectionTestQuery=select 1
    

    这样 Hikari 会在将其处理给 Hibernate 之前测试连接是否仍然存在。

    【讨论】:

    • 嗨,从 Hikari 文档来看,它适用于旧版驱动程序,而我们并非如此。 ?connectionTestQuery 如果您的驱动程序支持 JDBC4,我们强烈建议不要设置此属性。这适用于不支持 JDBC4 Connection.isValid() API 的“旧版”驱动程序。这是将在池中为您提供连接之前执行的查询,以验证与数据库的连接是否仍然存在。同样,尝试在没有此属性的情况下运行池,如果您的驱动程序不符合 JDBC4,HikariCP 将记录错误以通知您。默认值:无
    • 有趣,谢谢。我们在 MySQL 上遇到了类似的问题,添加 connectionTestQuery 帮助很大,所以现在我不确定发生了什么
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-03
    • 2013-02-19
    • 2012-07-31
    • 1970-01-01
    • 2018-10-05
    • 1970-01-01
    • 2018-01-04
    相关资源
    最近更新 更多