如何调试HikariCP丢失连接?

时间:2018-01-27 21:11:22

标签: mysql scala playframework 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 个答案:

没有答案