HikariCP的连接超时

时间:2019-06-12 19:52:41

标签: java spring-boot jdbc hikaricp

我有一个Spring Boot(v2.0.8)应用程序,该应用程序使用配置有以下内容的HikariCP(v2.7.9)池(连接到MariaDB)

minimumIdle: 1
maximumPoolSize: 10
leakDetectionThreshold: 30000

问题在于,我们的生产组件每隔几周就会反复抛出SQLTransientConnectionException " Connection is not available, request timed out after 30000ms..."。问题在于,它永远无法从中恢复,并且始终引发异常。因此,需要重新启动组分。

通过查看HikariPool源代码,似乎正在发生这种情况,因为每次调用connectionBag.borrow(timeout, MILLISECONDS)时poolEntry为null,因此抛出超时Exception。要使其为空,连接池必须没有空闲条目,即sharedList中的所有PoolEntry都标记为IN_USE

我不确定为什么组件无法从中恢复,因为最终我希望将PoolEntry标记为NOT_IN_USE,这会破坏重复的异常。

我能想到的可能场景:

  1. 所有条目均为IN_USE,并且数据库暂时关闭。我希望对运行中的查询抛出异常。也许此时,PoolEntry状态永远不会重置,因此会停留在IN_USE处。在这种情况下,我会想到如果抛出异常,则状态会更改,以便可以从池中清除连接。任何人都可以确认是否是这种情况吗?

  2. 向该组件发出大量REST请求,这又需要执行DB查询。这将填充连接池,因此后续请求超时,以等待先前的请求完成。这是有道理的,但是我希望组件在请求完成后能够恢复,但事实并非如此。

有人知道这里可能是什么问题吗?我已经尝试配置Hikari文档中的各种超时,但是没有诊断/解决此问题的运气。任何帮助将不胜感激。

谢谢!

1 个答案:

答案 0 :(得分:0)

方案2最有可能正在发生。当将它与云数据流一起使用并接收大量连接请求时,我遇到了相同的问题。我发现的唯一解决方案是使用配置来找到适用于我的用例的组合。

我将为您处理每秒50-100个请求的代码,并祝您好运。

private static DataSource pool;
final HikariConfig config = new HikariConfig();
config.setMinimumIdle(5);
config.setMaximumPoolSize(50);
config.setConnectionTimeout(10000);
config.setIdleTimeout(600000);
config.setMaxLifetime(1800000);
config.setJdbcUrl(JDBC_URL);
config.setUsername(JDBC_USER);
config.setPassword(JDBC_PASS);

pool = new HikariDataSource(config);