使用Spring Boot来检查HikariCP连接泄漏问题
在使用HikariCP的项目中遇到了连接池耗尽的问题,记录下了故障排除的方法。
确认环境。
-
- Spring Boot 2.2.2
-
- AdoptOpenJDK 11.0.3
- macOS Mojave 10.14.6
背景 – (Background)
在使用Spring Boot + HikariCP的Web应用程序中,当进行数据库连接时,发生了以下异常。
Caused by: java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 15006ms.
at com.zaxxer.hikari.pool.HikariPool.createTimeoutException(HikariPool.java:697) ~[HikariCP-3.4.1.jar:na]
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:196) ~[HikariCP-3.4.1.jar:na]
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:161) ~[HikariCP-3.4.1.jar:na]
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:128) ~[HikariCP-3.4.1.jar:na]
at org.springframework.jdbc.datasource.DelegatingDataSource.getConnection(DelegatingDataSource.java:99) ~[spring-jdbc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
...
从HikariCP引发的异常和15秒的超时可以推测出与application.yml的配置没有矛盾,可能是与连接池相关的问题。
spring:
datasource:
hikari:
connection-timeout: 15000
maximum-pool-size: 3
输出调试日志
通过启用HikariCP的调试日志,可以将连接池的状态(连接池中存在的连接数以及实际被使用的连接数)输出到日志中。
logging:
level:
+ com.zaxxer.hikari: debug
查看第二个日志,可以发现池中的三个连接都正在被使用,还有四个线程正在等待连接的空闲。
2020-05-01 16:03:13.859 DEBUG 79664 --- [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Pool stats (total=1, active=0, idle=1, waiting=0)
...
2020-05-01 16:03:43.866 DEBUG 79664 --- [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Pool stats (total=3, active=3, idle=0, waiting=4)
检测到连接泄漏
不仅能监测连接池的状态,还能检测连接池的泄漏(即连接泄漏),这将非常方便。HikariCP提供了用于此目的的设置leakDetectionThreshold。
spring:
datasource:
hikari:
connection-timeout: 15000
maximum-pool-size: 3
+ leak-detection-threshold: 5000
启用连接泄漏检测后,如果存在未释放的连接超过设定值(毫秒),将被记录为可能的泄漏并输出到日志中。这将有助于定位连接泄漏的发生位置。
2020-05-01 16:09:37.387 WARN 93600 --- [l-1 housekeeper] com.zaxxer.hikari.pool.ProxyLeakTask : Connection leak detection triggered for org.postgresql.jdbc.PgConnection@1d2d8846 on thread pool-2-thread-1, stack trace follows
java.lang.Exception: Apparent connection leak detected
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:128) ~[HikariCP-3.4.1.jar:na]
at org.springframework.jdbc.datasource.DelegatingDataSource.getConnection(DelegatingDataSource.java:99) ~[spring-jdbc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:158) ~[spring-jdbc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:116) ~[spring-jdbc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy$TransactionAwareInvocationHandler.invoke(TransactionAwareDataSourceProxy.java:226) ~[spring-jdbc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at com.sun.proxy.$Proxy106.createStatement(Unknown Source) ~[na:na]
...
总结
在这篇文章中,我们介绍了在遇到连接泄露时有用的HikariCP配置。
请提供更多上下文或具体的句子,以便我能够准确地进行翻译。
-
- https://github.com/brettwooldridge/HikariCP
- HikariCP で leakDetectionThreshold を設定して connection leak を検出する