我在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
的问题。