【问题标题】:HikariCP hanging on getConnectionHikariCP 挂在 getConnection 上
【发布时间】:2016-01-12 09:26:17
【问题描述】:

我有一个应用程序,它使用 HikariCP 对使用 JTDS 的 SQL Server DB 进行连接池。如果我让应用程序在一夜之间运行,那么早上第一个查询将挂起,并显示下面的堆栈跟踪。如果我再次请求,那么新的查询将正常工作。是否有我错过的超时会阻止第一个查询挂起?它似乎挂了大约 10-> 20 分钟,然后它开始工作。所以在 10->20 分钟后 sockRead 和挂起的线程消失了。我认为挂起的查询然后完成,但我可能是错的。我的 Hikari 配置也在下面。

java.lang.Thread.State: RUNNABLE
      at java.net.SocketInputStream.socketRead0(SocketInputStream.java:-1)
      at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
      at java.net.SocketInputStream.read(SocketInputStream.java:170)
      at java.net.SocketInputStream.read(SocketInputStream.java:141)
      at java.io.DataInputStream.readFully(DataInputStream.java:195)
      at java.io.DataInputStream.readFully(DataInputStream.java:169)
      at net.sourceforge.jtds.jdbc.SharedSocket.readPacket(SharedSocket.java:850)
      at net.sourceforge.jtds.jdbc.SharedSocket.getNetPacket(SharedSocket.java:731)
      - locked <0xeeb> (a java.util.concurrent.ConcurrentHashMap)
      at net.sourceforge.jtds.jdbc.ResponseStream.getPacket(ResponseStream.java:477)
      at net.sourceforge.jtds.jdbc.ResponseStream.read(ResponseStream.java:114)
      at net.sourceforge.jtds.jdbc.ResponseStream.peek(ResponseStream.java:99)
      at net.sourceforge.jtds.jdbc.TdsCore.wait(TdsCore.java:4127)
      at net.sourceforge.jtds.jdbc.TdsCore.executeSQL(TdsCore.java:1086)
      - locked <0xeec> (a net.sourceforge.jtds.jdbc.TdsCore)
      at net.sourceforge.jtds.jdbc.JtdsStatement.executeSQL(JtdsStatement.java:563)
      at net.sourceforge.jtds.jdbc.JtdsStatement.executeImpl(JtdsStatement.java:809)
      at net.sourceforge.jtds.jdbc.JtdsStatement.execute(JtdsStatement.java:1282)
      at com.zaxxer.hikari.pool.PoolElf.isConnectionAlive(PoolElf.java:224)
      at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:188)
      at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:163)
      at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:85)
      at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:204)
      at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
      at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)

Hikari 配置:

hconf.setJdbcUrl(url) // url looks like: jdbc:jtds:sqlserver://host/DB
hconf.setConnectionTestQuery("select 1")
hconf.setDriverClassName("net.sourceforge.jtds.jdbcx.JtdsDataSource")
// set username and password

hconf.setConnectionTimeout(5 * 1000)
hconf.setValidationTimeout(1000)
hconf.setIdleTimeout(10 * 60 * 1000)
hconf.setMaxLifetime(30 * 60 * 1000)
hconf.setLeakDetectionThreshold(60 * 1000)
hconf.setInitializationFailFast(false)
val numThreads = 10
hconf.setMaximumPoolSize(numThreads * 5)
hconf.setMinimumIdle(numThreads)
hconf.setPoolName(name)
hconf.setRegisterMbeans(false)

HikariCP:2.4.1

JTDS:1.3.1

更新:

我现在知道问题所在了。在 HikariCP isConnectionAlive 中,它会在调用setConnectionTestQuery 中的查询集之前尝试将网络超时设置为上面在setValidationTimeout 中指定的值。但是 JTDS 不支持java.sql.Connection.setNetworkTimeout,因此读取超时是操作系统的默认设置。大约需要 10 分钟。

理论上,您应该能够将驱动程序属性套接字超时设置为一种解决方法(尽管它对我不起作用)。但这不是一个很好的解决方法,因为您确实希望测试查询与实际查询的查询超时不同。

所以这不是 HikariCP 问题,而是 JTDS 问题。

【问题讨论】:

    标签: jtds hikaricp


    【解决方案1】:

    我建议通过 log4j 或您使用的任何日志框架为 HikariCP 包启用调试级别日志记录。 HikariCP 应该记录连接停用和创建,您可以使用它来验证连接是否在其配置的maxLifetime 正确循环。

    但是,查看您发布的堆栈跟踪,在 HikariCP isConnectionAlive() 检查期间,该线程似乎挂在 JTDS 驱动程序中。 HikariCP 在这方面无能为力。然而这很奇怪。

    您说“早上第一个查询将挂起”。电脑会休眠吗? SQL Server 会休眠吗?这样做会阻止 HikariCP 在夜间正常循环连接。同样,调试日志在这里会有所帮助——即使应用程序处于空闲状态,也应该在一夜之间进行相当定期的停用和创建活动。

    【讨论】:

    • 谢谢布雷特。你是对的,这似乎是一个 JTDS 问题(请参阅我在问题中的更新)。你对我的电脑(我安装了我的开发 SQL 服务器的地方)要睡觉也是对的。直到出现这个问题,我才意识到它在晚上会这样做。您知道在 JTDS 中实现缺少的 setNetworkTimeout 调用的任何方法吗?似乎很多 JDBC 驱动程序都缺少此功能。
    【解决方案2】:

    如果您更新到 2.4.3,它会在 getConnection() 和其他一些/类似情况下解决问题的细微变化。 请报告它是否解决或在行为或堆栈跟踪方面产生任何差异

    【讨论】:

    • 我已经升级了。我会在接下来的几天内密切关注并报告。
    • @Dave 想知道您的升级是否解决了您的问题。谢谢!
    • @javadev 我用我发现的内容更新了问题(参见“更新:”部分)。结果证明不是光问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-28
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 2012-12-30
    相关资源
    最近更新 更多