简体   繁体   English

与HikariCP的连接超时

[英]Connection timeouts with HikariCP

I have a Spring Boot (v2.0.8) application which makes use of a HikariCP (v2.7.9) Pool (connecting to MariaDB) configured with: 我有一个Spring Boot(v2.0.8)应用程序,该应用程序使用配置有以下内容的HikariCP(v2.7.9)池(连接到MariaDB):

minimumIdle: 1
maximumPoolSize: 10
leakDetectionThreshold: 30000

The issue is that our production component, once every few weeks, is repeatedly throwing SQLTransientConnectionException " Connection is not available, request timed out after 30000ms..." . 问题是我们的生产组件每隔几周就会反复抛出SQLTransientConnectionException " Connection is not available, request timed out after 30000ms..." The issue is that it never recovers from this and consistently throws the exception. 问题是它永远不会从中恢复并始终抛出异常。 A restart of the componnent is therefore required. 因此需要重新启动组件。

From looking at the HikariPool source code, it would seem that this is happening because every time it is calling connectionBag.borrow(timeout, MILLISECONDS) the poolEntry is null and hence throws the timeout Exception. 通过查看HikariPool源代码,似乎发生了这种情况,因为每次调用connectionBag.borrow(timeout, MILLISECONDS) ,poolEntry都为null,因此会抛出超时异常。 For it to be null, the connection pool must have no free entries ie all PoolEntry in the sharedList are marked IN_USE . 如果它为null,则连接池必须没有空闲条目,即sharedList中的所有PoolEntry都标记为IN_USE

I am not sure why the component would not recover from this since eventually I would expect a PoolEntry to be marked NOT_IN_USE and this would break the repeated Exceptions. 我不确定为什么组件不会从此恢复,因为最终我希望PoolEntry被标记为NOT_IN_USE ,这将打破重复的异常。

Possible scenarios I can think of: 我能想到的可能场景:

  1. All entries are IN_USE and the DB goes down temporarily. 所有条目都是IN_USE ,DB暂时中断。 I would expect Exceptions to be thrown for the in-flight queries. 我希望在飞行中查询会抛出异常。 Perhaps at this point the PoolEntry status is never reset and therefore is stuck at IN_USE . 也许在这一点上,PoolEntry状态永远不会被重置,因此会停留在IN_USE In this case I would have thought if an Exception is thrown the status is changed so that the connection can cleared from the pool. 在这种情况下,我会想到如果抛出异常,状态会发生变化,以便可以从池中清除连接。 Can anyone confirm if this is the case? 任何人都可以确认是否是这种情况?

  2. A flood of REST requests are made to the component which in turn require DB queries to be executed. 向组件发出大量REST请求,而这些请求又需要执行DB查询。 This fills the connection pool and therefore subsequent requests timeout waiting for previous requests to complete. 这将填充连接池,因此后续请求会超时等待先前的请求完成。 This makes sense however I would expect the component to recover once the requests complete, which it is not. 这是有道理的但是我希望组件在请求完成后恢复,但事实并非如此。

Does anyone have an idea of what might be the issue here? 有没有人知道这里可能存在什么问题? I have tried configuring the various timeouts that are in the Hikari documentation but have had no luck diagnosing / resolving this issue. 我已经尝试配置Hikari文档中的各种超时,但没有运气诊断/解决此问题。 Any help would be appreciated. 任何帮助,将不胜感激。

Thanks! 谢谢!

Scenario 2 is most likely what is happening. 场景2最有可能发生的事情。 I ran into the same issue when using it with cloud dataflow and receiving a large amount of connection requests. 在将其与云数据流一起使用并接收大量连接请求时,我遇到了同样的问题。 The only solution I found was to play with the config to find a combination that worked for my use case. 我找到的唯一解决方案是使用配置来查找适用于我的用例的组合。

I'll leave you my code that works for 50-100 requests per second and wish you luck. 我会给你留下每秒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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM