先确认是否真被连接数打满:用ss命令查ESTABLISHED总数及3306端口分布,结合SHOW PROCESSLIST中Threads_connected远大于Threads_running且大量Sleep超时,可判定为空闲连接堆积而非真实并发压力。

确认是否真被连接数打满
Host 网络模式下,容器直接使用宿主机网络栈,所有 TCP 连接都体现在宿主机上。别一上来就怀疑 MySQL 或应用,先看底层连接状态:
- 查当前 ESTABLISHED 连接总数:ss -ant | grep ESTAB | wc -l
- 按目标端口(比如 MySQL 的 3306)统计:ss -ant | grep :3306 | grep ESTAB | wc -l
- 看每个客户端 IP 的连接分布:ss -ant | grep :3306 | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head -10
如果某个 IP 连接数异常高(比如单个应用实例连出 200+),基本可锁定是它没释放连接或配置失当。
区分是应用层连接池打满,还是系统级资源耗尽
Host 网络不经过 Docker NAT,但依然受限于 Linux 内核参数。要同步排查两层:
- 应用侧:检查连接池配置(如 HikariCP 的 maximum-pool-size 和 leak-detection-threshold),确认是否有连接泄漏日志
- 系统侧:运行 ulimit -n 查进程文件描述符上限;用 cat /proc/$(pgrep mysqld)/limits | grep "Max open files" 看 MySQL 实际能打开的 fd 数
- 若 ss -s 显示 total: 65535 但 tcp: 65535 已用光,说明不是应用问题,是系统级连接数见顶
快速释放无效连接 & 临时缓解
Host 模式下没有容器网络隔离,操作更直接,但也更需谨慎:
- 清空 TIME_WAIT 过多的连接(慎用,仅应急):echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
- 缩短 TIME_WAIT 超时(需配合内核调优):echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
- 强制终止某类连接(如全部到 3306 的非本地连接):ss -ant | grep :3306 | grep -v 127.0.0.1 | awk '{print $7}' | xargs -r kill -9(仅限紧急断连,勿在生产随意执行)
根因聚焦:MySQL 连接是否真的在用?
Host 网络让 MySQL 的 SHOW PROCESSLIST 更具参考价值——它反映的是真实 TCP 连接状态,不是容器网络抽象层后的视图:
- 重点看 State 列:大量 Sleep 且 Time 超过 60 秒,说明应用获取连接后没关闭
- 查长期运行的线程:SELECT * FROM information_schema.PROCESSLIST WHERE TIME > 60 AND COMMAND != 'Sleep';
- 结合 Threads_connected 和 Threads_running:若前者远大于后者,就是空闲连接堆积,不是并发压力大
Host 网络本身不制造连接,只暴露问题。真正打满的,从来不是网络,而是没归还的连接、没结束的事务、没设超时的 HTTP 调用。


















