HikariCP 空闲连接在连接池中保持活动状态

Posted

技术标签:

【中文标题】HikariCP 空闲连接在连接池中保持活动状态【英文标题】:HikariCP Idle connections staying in connection pool as active 【发布时间】:2018-11-06 08:30:51 【问题描述】:

我正在使用 Spring Boot (1.5.6)、Hibernate、Postgres、Hikari (2.7.8)。我的配置是:

spring.datasource.hikari.minimumIdle=1
spring.datasource.hikari.maximumPoolSize=20
spring.datasource.hikari.idleTimeout=30000
spring.datasource.hikari.poolName=SpringBootJPAHikariCP
spring.datasource.hikari.maxLifetime=50000
spring.datasource.hikari.connectionTimeout=30000

我期望的是,空闲连接应该在30000 ms/30 秒空闲后释放。 问题在于每个请求都建立新连接,而所有空闲连接都保持原样。因此,经过一段时间后,我得到了 20 个空闲连接,并收到了一个新请求 Hikari 尝试获得一个新连接并获得 SpringBootJPAHikariCP - Connection is not available, request timed out after 30001ms.

那么,我做错了什么。?还是对配置有误解?

Hikari 初始化日志:

SpringBootJPAHikariCP - configuration:
 allowPoolSuspension.............false
 autoCommit......................true
 catalog.........................none
 connectionInitSql...............none
 connectionTestQuery.............none
 connectionTimeout...............30000
 dataSource......................none
 dataSourceClassName.............none
 dataSourceJNDI..................none
 dataSourceProperties............password=<masked>
 driverClassName................."org.postgresql.Driver"
 healthCheckProperties...........
 healthCheckRegistry.............none
 idleTimeout.....................30000
 initializationFailFast..........true
 initializationFailTimeout.......1
 isolateInternalQueries..........false
 jdbc4ConnectionTest.............false
 jdbcUrl.........................jdbc:postgresql://localhost:5432/dbname
 leakDetectionThreshold..........0
 maxLifetime.....................50000
 maximumPoolSize.................20
 metricRegistry..................none
 metricsTrackerFactory...........none
 minimumIdle.....................1
 password........................<masked>
 poolName........................"SpringBootJPAHikariCP"
 readOnly........................false
 registerMbeans..................false
 scheduledExecutor...............none
 scheduledExecutorService........internal
 schema..........................none
 threadFactory...................internal
 transactionIsolation............default
 username........................"postgres"
 validationTimeout...............5000

更新: 在过去的 24 小时内,我尝试了来自不同线程的几种解决方案,但都没有解决我的问题。所以这里有一些可能很重要的观察结果。

    SpringBootJPAHikariCP - Reset (autoCommit) on connection org.postgresql.jdbc.PgConnection@1344bbf1 找到了这个日志。研究过 Reset (autoCommit) on connection in HikariCP 这个帖子。尝试在两侧(休眠和 Hikari)设置 auto commit 相同(true)并在两侧尝试使用 false。还是没有运气。

    启用leakDetectionThreshold,得到泄漏检测异常。所以试图了解休眠/弹簧事务管理器是否释放连接。从下面的日志来看,hibernate 工作正常。

    28 22:19:35- DEBUG - o.s.orm.jpa.JpaTransactionManager-371 ::  Opened new EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@4212be39] for JPA transaction
    28 22:19:35- DEBUG - o.h.e.t.internal.TransactionImpl-51 ::  begin
    28 22:19:35- DEBUG - o.s.orm.jpa.JpaTransactionManager-403 ::  Exposing JPA transaction as JDBC transaction [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@243e942]
    2com.someentity.MyEntity#ac918eed-345f-4a6c-8539-fe14e7fc41e2
    28 22:19:35- DEBUG - o.h.r.j.i.LogicalConnectionManagedImpl-137 ::  Initiating JDBC connection release from afterTransaction
    28 22:19:35- DEBUG - c.zaxxer.hikari.pool.ProxyConnection-242 ::  SpringBootJPAHikariCP - Executed rollback on connection org.postgresql.jdbc.PgConnection@1344bbf1 due to dirty commit state on close().
    28 22:19:35- DEBUG - o.h.e.i.AbstractFlushingEventListener-132 ::  Processing flush-time cascades
    28 22:19:35- DEBUG - o.h.e.i.AbstractFlushingEventListener-174 ::  Dirty checking collections
    
    28 22:19:35- DEBUG - org.hibernate.internal.SessionImpl-508 ::  Disconnecting session
    28 22:19:35- DEBUG - o.s.orm.jpa.JpaTransactionManager-759 ::  Initiating transaction commit
    28 22:19:35- DEBUG - o.s.orm.jpa.JpaTransactionManager-512 ::  Committing JPA transaction on EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@4212be39]
    28 22:19:35- DEBUG - o.h.e.t.internal.TransactionImpl-62 ::  committing
    28 22:19:35- DEBUG - o.h.r.j.i.LogicalConnectionManagedImpl-137 ::  Initiating JDBC connection release from afterTransaction
    28 22:19:35- DEBUG - o.h.r.j.i.LogicalConnectionManagedImpl-137 ::  Initiating JDBC connection release from afterTransaction
    28 22:19:35- DEBUG - o.s.orm.jpa.JpaTransactionManager-600 ::  Closing JPA EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@4212be39] after transaction
    28 22:19:35- DEBUG - o.s.o.jpa.EntityManagerFactoryUtils-435 ::  Closing JPA EntityManager
    

    所有空闲连接a都是idle形式postgres观点和active形式Hikari观点。所以当数据库有5个空闲连接时,Hikari日志中有toatal = 5, active=4, idle = ,waiting=0

注意:

    可能是我遇到了这个确切的问题https://github.com/brettwooldridge/HikariCP/issues/109,在我的情况下,活动连接随着每笔交易的增加而增加。

    HikariCP - connection is not available 这也是同样的问题。但没有人为此提供明确的解决方案。顺便说一句,我按照接受的答案的建议从乞讨中使用@Transactional

【问题讨论】:

您的代码没有返回连接池。这与 idleTimeout 配置设置无关。 我该如何解决这个问题。有什么建议或资源可以阅读。?顺便说一句,我在连接池问题上相当新。 启用leakDetectionThreshold 并查看泄漏堆栈跟踪日志。 在启用leakDetectionThreshold 后出现多个泄漏检测异常。所以可能不是它自己的池,可能是我的应用程序做错了什么。仍然接受建议 @brettw 你能检查我对这个问题的更新吗?仍然坚持这个问题。 【参考方案1】:

这不是任何 Hikari 问题,我的结果是一个错误。仍在发布有关如何发生的详细信息,以防它对某人有所帮助。

我使用的是spring boot 1.5.6(这是我开始工作时的最新版本)。 此版本包括spring-orm 4.3.1。此版本的spring-orm 支持三个版本的hibernate,Hibernate5Hibernate4Hibernate3

所以我为current_session_context_class配置了以下配置的spring boot。

spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext

在 Hikari 的连接管理之前一切正常。发生的事情是 spring-boot-starter-jpa 对于 1.5.6 包括 Hibernate5 (我的意思是休眠核心)。

因此,在执行任何数据库操作后,弹簧会失去对该连接的控制(此版本不匹配的可能性最大)。于是就有了问题。

改变后

org.springframework.orm.hibernate4.SpringSessionContext

org.springframework.orm.hibernate5.SpringSessionContext

问题马上解决了。

我目前的配置是

spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL95Dialect

仅供参考,解决问题后切换到Spring Boot 2。

【讨论】:

你好@saif,你能为我推荐配置吗,因为在阅读了你的帖子后,我也无法解决我的 hikari 池问题

以上是关于HikariCP 空闲连接在连接池中保持活动状态的主要内容,如果未能解决你的问题,请参考以下文章

DBCP连接池介绍

DBCP连接池介绍

Websocket客户端重新连接空闲连接

HikariCP 未在 close() 上关闭连接(连接泄漏)

Druid连接池

Facebook 聊天 tcp 连接如何保持活动状态?