如何调试HikariCP丢失连接?

我在Play 2.6.10中使用HikariCP . 应用程序将运行好几天,然后我们所有的连接都会泄漏 . 我打开 leakDetectionThreshold ,所以我们得到泄漏连接的堆栈跟踪,例如:

2018-01-24 06:29:00,857 - [WARN] - from com.zaxxer.hikari.pool.ProxyLeakTask in 
HikariPool-2 housekeeper 
Connection leak detection triggered for com.mysql.jdbc.JDBC4Connection@65cd084 on thread pool-1-thread-1, stack trace follows
java.lang.Exception: Apparent connection leak detected
        at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.jav
a:85)
        at play.api.db.DefaultDatabase.getConnection(Databases.scala:142)
        at play.api.db.DefaultDatabase.withConnection(Databases.scala:152)
        at play.api.db.DefaultDatabase.withConnection(Databases.scala:148)
        at models.summaries.ActionSummary$.listByStripe(ActionSummary.scala:137)

我只使用Play的 withConnection 连接,因此它们应该自动返回池中 . 当应用程序处于损坏状态时,线程转储显示 withConnection 块内的所有线程都被卡住了...

"application-akka.mysql-context-122" #32142 prio=5 os_prio=0 tid=0x00007fca7812a
000 nid=0x28e6 waiting on condition [0x00007fca7541c000]
   java.lang.Thread.State: TIMED_WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for   (a java.util.concurrent.Sync
hronousQueue$TransferQueue)
        at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215
)
        at java.util.concurrent.SynchronousQueue$TransferQueue.awaitFulfill(Sync
hronousQueue.java:764)
        at java.util.concurrent.SynchronousQueue$TransferQueue.transfer(Synchron
ousQueue.java:695)
        at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)
        at com.zaxxer.hikari.util.ConcurrentBag.borrow(ConcurrentBag.java:157)
        at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:165)
        at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:147)
        at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:85)
        at play.api.db.DefaultDatabase.getConnection(Databases.scala:142)
        at play.api.db.DefaultDatabase.withConnection(Databases.scala:152)
        at play.api.db.DefaultDatabase.withConnection(Databases.scala:148)

...等待连接可用,这意味着当前没有连接 . 我不知道有什么连接可能被泄露,但显然他们都有 . 我们看到日志行如下:

2018-01-24 06:19:21,297 - [DEBUG] - from com.zaxxer.hikari.pool.HikariPool in application-akka.mysql-context-129 
HikariPool-2 - Timeout failure stats (total=10, active=10, idle=0, waiting=15)

我们唯一不寻常的事情是在我们获得的每个连接上调用 setNetworkTimeout ,有时超时低至10秒 . 这样做是为了确保如果我们失去与DB的连接,查询会快速失败 .

我不知道下次调试这个怎么办 . 它看起来可能是Hikari和Play之间的潜在问题,或者是MySQL和 setNetworkTimeout 之类的问题 .

回答(0)