mysql服务端wait_timeout设太短会直接断连云环境连接,常见于云厂商rds或轻量镜像中被调至60–300秒;需检查并调高该值,同时确保连接池maxidletime小于wait_timeout,并配置tcp keepalive及slb超时协同。

MySQL服务端wait_timeout设太短会直接断连
云环境里最常见的连接中断,不是网络抖动,而是MySQL自己把空闲连接关了。默认wait_timeout是28800秒(8小时),但很多云厂商RDS或自建ECS上的MySQL被悄悄调成了300秒甚至60秒——尤其在轻量应用模板或一键部署镜像中。
检查当前值:SHOW VARIABLES LIKE 'wait_timeout';
- 如果返回值 ≤ 300,基本可以确定是它在“主动杀连接”
- 临时调高:执行
SET GLOBAL wait_timeout = 600;(单位秒) - 必须写入配置文件持久化,否则重启失效;在
/etc/my.cnf的[mysqld]段下加:[mysqld] wait_timeout = 600 interactive_timeout = 600
- 注意:
interactive_timeout只影响mysql命令行等交互式客户端,应用连接走的是wait_timeout,别搞混
客户端连接池maxIdleTime必须比wait_timeout小
哪怕MySQL允许连接空闲600秒,如果你用HikariCP或Druid,却把maxIdleTime设成1800000(30分钟),那连接池里的连接大概率会在MySQL关闭前就“自我淘汰”,再取出来时已是失效连接,抛Communications link failure。
- HikariCP示例:
spring.datasource.hikari.max-idle-time=300000(5分钟),必须 wait_timeout(建议留20%余量) - Druid示例:
spring.datasource.druid.max-wait=3000是获取连接超时,不是空闲超时;真正管空闲的是min-evictable-idle-time-millis,应设为300000左右 - 务必开启连接有效性验证:
validationQuery=SELECT 1+testOnBorrow=true(或Hikari的connection-test-query)
云平台自带的网络层超时比MySQL还狠
ECS实例所在的安全组、SLB负载均衡器、NAT网关,甚至某些VPC路由策略,都内置了TCP空闲连接自动断开机制。阿里云SLB默认是900秒,腾讯云CLB是1800秒,AWS ALB是3600秒——它们不看MySQL心跳,只看TCP包是否活跃。
- 最稳做法:在MySQL客户端驱动里启用TCP keepalive,例如JDBC URL加参数:
?tcpKeepAlive=true&socketTimeout=30000 - Linux系统级补充(ECS上执行):
echo 'net.ipv4.tcp_keepalive_time = 300' >> /etc/sysctl.conf echo 'net.ipv4.tcp_keepalive_intvl = 60' >> /etc/sysctl.conf echo 'net.ipv4.tcp_keepalive_probes = 3' >> /etc/sysctl.conf sysctl -p
- 不要依赖
autoReconnect=true(MySQL JDBC已弃用),它无法恢复事务上下文,只适合简单查询场景
max_connect_errors误触发会导致IP被锁死
云环境DNS波动、容器重启、LB健康检查失败,都可能让同一IP在100秒内触发多次连接失败。一旦超过max_connect_errors(默认100),MySQL会直接拒绝该IP后续60秒所有连接,现象就是“突然连不上”,查日志看到Host 'xxx' is blocked because of many connection errors。
- 临时解封:
FLUSH HOSTS; - 长期预防:在
my.cnf中提高阈值:[mysqld] max_connect_errors = 200
- 配合监控:
SHOW STATUS LIKE 'aborted_connects';持续上涨就要排查是网络问题还是应用重试逻辑失控
wait_timeout设了1200秒,这时所有“空闲连接复用”都会失败,且错误日志里根本不会提SLB。











