事情本身不复杂,线索都在日志里。每天早上第一批请求必报 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,活跃连接曲线平稳。

连接生命周期要比服务端空闲超时短,一般取服务端的八成;负载均衡的空闲超时也要一起看,否则中间层先断。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。

作者 9823189