HikariPool连接不可用
mysql数据库由5.7迁移到8.0后,测试环境应用控制台报获取数据库连接不可用,请求超时,数据库连接池使用的HikariPool,异常如下:
Caused by: java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 10050ms.
mysql数据库版本是8.0.32
1、查看应用配置如下:
connectionTimeout: 10000
maximumPoolSize: 20
缺少以下配置:
maxLifetime最大存活时长,超时而且没被使用则被释放(retired),缺省:30分钟
idleTimeout闲置的最长时间,仅适用于minimumIdle设置为小于maximumPoolSize的情况 默认:600000(10minutes)
minimumIdle:最小空闲连接数minimumIdle,根据业务场景,设置为10,小于maximumPoolSize值
2、show variables like '%timeout%'查看数据库超时配置:
interactive_timeout和wait_timeout默认都是28800秒,即8小时。表明数据库默认8小时后才会自动断开连接。
3、show variables like '%connection%'查看数据库最大连接数
max_connections值为3000,所以不存在数据库连接不够的情况,当前连接池最大连接数是20个,即使10个连接池都占满未释放也才200个。
4、比对线上数据库配置interactive_timeout和wait_timeout都是900秒,即15分钟,说明线上数据库是有自我保护配置,小于应用的超时时间,所以再检查日志,会出现:
com.zaxxer.hikari.pool.PoolBase - HikariPool-1 - Failed to validate connection com.mysql.cj.jdbc.ConnectionImpl@3ca25226 (No operations allowed after connection closed.). Possibly consider using a shorter maxLifetime value.
这里有个疑问:如果被数据库断开连接,从连接池中获取的连接是否有效(连接池对连接检查是否有用,如果获取连接前都会作此校验,应该不会出现问题),目前线上未出现获取连接超时的问题。
这里建议数据库连接池核心配置不要默认,需要设置合适的且不能大于数据库的配置。
5、大概率是连接池本身的连接长时间占用未释放,未排除长事务存在的可能,后续可以将连接池的信息打印出来,当前在不修改测试环境数据库配置的情况下,只修改应用端连接池配置,加上以下配置:
maxLifetime: 600000
idleTimeout: 180000
minimumIdle: 5
6、重启应用后,目前未出现异常情况,通过show processlist可以查看mysql服务器上各数据库的会话情况。
7、查看数据库状态show status like '状态名称'
通过show status like 'Max_used_connections'查看数据库服务器从启动到当前时间的最大并发连接数。
show status查看所有状态
参考:Hikaricp连接池问题_hikari数据库连接池被占满无法释放-CSDN博客