上云后mysql默认wait_timeout导致应用层很多连接不可用
1. 现象
系统部署在阿里云服务器中,mysql正常部署,但业务系统经常报错,几种报错的内容如下
①. Connection com.mysql.cj.jdbc.ConnectionImpl@45ed27d2 marked as broken because of SQLSTATE(08S01), ErrorCode(1160)
②. Could not roll back JDBC transaction: nested exception is java.sql.SQLException: Connection is closed
③. Could not open JDBC Connection for transaction; nested exception is com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

2. 原因
为什么云服务器(阿里云、腾讯云)通常更需要把 timeout 设小?
在云环境中,网络设备会主动清理“长时间不活跃的 TCP 连接”,包括:
• 云防火墙
• SLB(负载均衡)
• VPC 虚拟网络
• 安全组防火墙
• NAT 网关
• TCP keepalive 机制
这些设备都会 “默默” 关闭长时间不活跃的连接。
因此,如果你把 wait_timeout 设置很大,会发生什么?
应用层以为连接还在
但底层网络已经把 TCP 连接关闭
下一次用这个连接时就会抛异常:
Communications link failure
mysql默认的wait_timeout: 28800 单位秒,8小时。
这在平时开发测试环境是没有问题的;但上云后会出现这样的问题;
3. 解决
3.1 mysql服务器修改wait_timeout
# 设置非交互连接的超时时间
wait_timeout = 900 # 15 分钟
interactive_timeout = 900 # 15 分钟
重启mysql
systemctl restart mysql
验证生效
SHOW VARIABLES LIKE 'wait_timeout';
3.2 业务系统连接池的配置修改
这里以HikariCP为例。
datasource:
hikari:
# 连接池中允许的最大连接数 (默认: 10)
maximum-pool-size: 20
# 连接池中保持的最小空闲连接数 (建议与maximum-pool-size相同)
minimum-idle: 2
# 连接超时时间 (毫秒) (默认: 30000)
connection-timeout: 30000
# 连接最大存活时间 (毫秒) (建议比数据库wait_timeout小2-3分钟)
max-lifetime: 840000 # 15分钟
# 连接空闲超时时间 (毫秒) (默认: 600000)
idle-timeout: 600000 # 10分钟
# 连接测试查询 (部分数据库需要)
connection-test-query: SELECT 1
核心就是max-lifetime < mysql中的wait_timeout
2345

被折叠的 条评论
为什么被折叠?



