事情本身不复杂,线索都在日志里。每天早上第一批请求必报 Communications link failure,白天完全正常,MySQL 的 wait_timeout 是 28800,应用连接池 maxLifetime 配的是 3600000 毫秒。
第一反应是「中间还有一层负载均衡,空闲连接被静默丢弃」,验证下来不成立。
这类报错背后常见的原因有几处,逐个排除就行。连接空闲超过服务端 wait_timeout 被断开,池里还留着。也可能是连接池没开保活检测,坏连接一直在借出。
还有一种情况,数据库侧空闲会话被运维脚本主动 kill。
上来先对比两边的空闲超时设置
mysql -e "show variables like '%timeout%';" | grep -E 'wait_timeout|interactive_timeout'
接着把客户端生命周期压到服务端之下
mysql -e "set global wait_timeout=600;"
借出前做一次连接有效性检测
mysql -e "select 1;"
模拟空闲超过十分钟后再请求
for i in 1 2 3; do mysql -h 10.0.0.20 -e 'select now();'; sleep 700; done
改完先别撤,确认这几项。空闲超过十分钟后的第一批请求全部成功,日志里不再出现 Communications link failure,活跃连接曲线平稳。
连接生命周期要比服务端空闲超时短,一般取服务端的八成;负载均衡的空闲超时也要一起看,否则中间层先断。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。
