java - HikariCP 连接超时

标签 java spring-boot jdbc hikaricp

我有一个 Spring Boot (v2.0.8) 应用程序,它使用 HikariCP (v2.7.9) 池(连接到 MariaDB),配置如下:

minimumIdle: 1
maximumPoolSize: 10
leakDetectionThreshold: 30000

问题是我们的生产组件每隔几周就会重复抛出SQLTransientConnectionException“连接不可用,请求在 30000 毫秒后超时...”。问题是它永远不会从中恢复并始终抛出异常。因此需要重新启动组件。

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

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

我能想到的可能场景:

  1. 所有条目均处于IN_USE状态,并且数据库暂时关闭。我希望飞行中的查询会抛出异常。也许此时 PoolEntry 状态永远不会重置,因此停留在 IN_USE 状态。在这种情况下,我会认为如果抛出异常,状态就会改变,以便可以从池中清除连接。谁能确认一下情况是否如此?

  2. 向组件发出大量 REST 请求,而这些请求又需要执行数据库查询。这会填满连接池,因此后续请求会超时等待先前的请求完成。这是有道理的,但我希望组件在请求完成后恢复,但事实并非如此。

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

谢谢!

最佳答案

场景 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);

关于java - HikariCP 连接超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56569495/

相关文章:

java - Servlet 过滤器和 OSGi HttpService

java - spring 是否有办法在应用程序首次加载时加载东西?在全局范围内

java - 如何为 HTML 简单文本制作正则表达式模式?

java - Playframework:发生 JPA 错误(无法构建 EntityManagerFactory)

java - 将 Jetty 迁移到 SpringBoot Jetty

java - 如何在 Spring Boot 中记录 Rest Web 服务所花费的时间?

sql - Derby 类路径无法连接到数据库

java - 无法将对象转换为实体类型

java - JDBC 的 Connection 和 Statement 对象是按引用传递还是按值传递?

java - 将Java连接到MySQL数据库