聊聊hikari连接池的maxLifetime属性及evict操作

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了聊聊hikari连接池的maxLifetime属性及evict操作相关的知识,希望对你有一定的参考价值。

参考技术A 本文主要研究一下hikari连接池的maxLifetime属性及evict操作

用来标记连接池中的连接不可用,这样在borrow连接的时候,如果是标记evict的,则会继续获取连接

HikariCP-2.7.6-sources.jar!/com/zaxxer/hikari/pool/HikariPool.java

HikariCP-2.7.6-sources.jar!/com/zaxxer/hikari/pool/HikariPool.java

hikari连接池的maxLifetime用来标记connection在连接池中的存活时间,为0表示无限期。其到期的操作,主要是依靠在创建poolEntry的时候,注册一个延时任务,在连接存活将要到达maxLifetime之前触发evit,用来防止出现大面积的connection因maxLifetime同一时刻失效。除了这个延时任务,用户也可以主动去调用evict标记连接为evict。

触发时间距离maxlifetime的差值是根据 maxLifetime > 10_000 ? ThreadLocalRandom.current().nextLong( maxLifetime / 40 ) : 0;
来计算( up to 2.5% of the maxlifetime )。

标记为evict只是表示连接池中的该连接不可用,但还在连接池当中,还会被borrow出来,只是getConnection的时候判断了,如果是isMarkedEvicted,则会从连接池中移除该连接,然后close掉。

可能考虑使用更短的 maxLifetime 值 - hikari 连接池 spring boot

【中文标题】可能考虑使用更短的 maxLifetime 值 - hikari 连接池 spring boot【英文标题】:Possibly consider using a shorter maxLifetime value - hikari connection pool spring boot 【发布时间】:2020-06-04 05:49:44 【问题描述】:

启动我的 SpringBoot 应用程序后,在服务器启动几分钟后出现异常。没有在外部使用任何 HikariPool 配置,Spring Boot 默认使用 HikariPool 这是我在控制台中遇到的错误:

2020-02-20 03:16:23 - HikariPool-4 - Failed to validate connection 
com.mysql.cj.jdbc.ConnectionImpl@4c4180c8 (No operations allowed after connection closed.). 
Possibly consider using a shorter maxLifetime value.
2020-02-20 03:16:28 - HikariPool-4 - Failed to validate connection 
com.mysql.cj.jdbc.ConnectionImpl@679c2f50 (No operations allowed after connection closed.). 
Possibly consider using a shorter maxLifetime value.
2020-02-20 03:16:33 - HikariPool-4 - Failed to validate connection 
com.mysql.cj.jdbc.ConnectionImpl@16083061 (No operations allowed after connection closed.). 
Possibly consider using a shorter maxLifetime value.
2020-02-20 03:16:38 - HikariPool-4 - Failed to validate connection 
com.mysql.cj.jdbc.ConnectionImpl@4fcaf421 (No operations allowed after connection closed.). 
Possibly consider using a shorter maxLifetime value.
2020-02-20 03:16:43 - HikariPool-4 - Failed to validate connection 
com.mysql.cj.jdbc.ConnectionImpl@33df5d54 (No operations allowed after connection closed.). 
Possibly consider using a shorter maxLifetime value.
2020-02-20 03:16:48 - HikariPool-4 - Failed to validate connection 
com.mysql.cj.jdbc.ConnectionImpl@373d288c (No operations allowed after connection closed.). 
Possibly consider using a shorter maxLifetime value.
2020-02-20 03:16:48 - SQL Error: 0, SQLState: 08003
2020-02-20 03:16:48 - HikariPool-4 - Connection is not available, request timed out after 
30156ms.
2020-02-20 03:16:48 - No operations allowed after connection closed.
2020-02-20 03:16:48 - Servlet.service() for servlet [dispatcherServlet] in context with path 
[] threw exception [Request processing failed; nested exception is 
org.springframework.dao.DataAccessResourceFailureException: Unable to acquire JDBC 
Connection; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to 
acquire JDBC Connection] with root cause

【问题讨论】:

什么是root cause 这里是完整的异常堆栈: 【参考方案1】:

就我而言,我通过这个设置解决了这个问题

@Configuration
public class HikariSetting

    @Bean
    public HikariConfig config() 
        HikariConfig hikariConfig = new HikariConfig();
        
        // other setting
        
        hikariConfig.addDataSourceProperty("socketTimeout", 600000);
        hikariConfig.setMaxLifetime(600000);
        
        return hikariConfig;
    
    

参考this

【讨论】:

您不需要定义 bean,只需在 application.properties 中提供适当的属性,建议通过替换 bean 来解决此问题不是正确的解决方案。【参考方案2】:

您可以在 application.properties 文件中设置如下值

spring.datasource.hikari.maxLifeTime : 600000 #10分钟等待时间

【讨论】:

【参考方案3】:

问题在于 spring.datasource.hikari.maxLifetime 的默认值(30 分钟 - https://github.com/brettwooldridge/HikariCP#configuration-knobs-baby)高于数据库的“wait_timeout”(在我的情况下为 10 分钟)。 所以你有两个选择,要么将 hikari.maxLifetime 减少到 10 分钟以下,要么增加数据库的“wait_timeout”属性。

【讨论】:

你知道这是我们必须设置该值的属性吗? spring.datasource.hikari.max-lifetime=600000(以毫秒为单位) 我使用 wait_timeout = 300(5 分钟)和 max-lifetime = 600000(10 分钟)进行了测试。但是我无法收到此错误。你知道为什么吗? @CanattoFilipe 当应用程序尝试使用它假定处于活动状态的旧连接池(早于 DB wait_timeout)与 DB 交互时,会发生错误。所以我认为你应该试着模拟一下。 RAVI SHANKAR 的答案是最好的,因为它告诉我们“这样做是为了解决”而不是“找出如何解决”

以上是关于聊聊hikari连接池的maxLifetime属性及evict操作的主要内容,如果未能解决你的问题,请参考以下文章

聊聊hikari连接池的leakDetectionThreshold

可能考虑使用更短的 maxLifetime 值 - hikari 连接池 spring boot

hikari连接池的logintimeout设置过大会造成啥后果

spring常见错误数据库idleTimeout is close to or more than maxLifetime, disabling it.

spring常见错误数据库idleTimeout is close to or more than maxLifetime, disabling it.

spring常见错误数据库idleTimeout is close to or more than maxLifetime, disabling it.