tcp连接暴增导致负载飙升时,需分层定位瓶颈:先查ss-s中的established、close_wait、time_wait状态分布,再用ss和lsof下钻源ip、端口及进程socket数,接着确认ulimit、somaxconn和内存是否触顶,最后结合vnstat、nginx日志和iftop比对基线与流量行为判定异常。

TCP 应用连接数暴增后系统负载飙升,不能只盯着 CPU 或 load average 看——真正瓶颈往往藏在连接状态、资源耗尽点和应用行为里。先确认是不是真过载,再分层定位是哪一层在“堵”。
看连接状态分布,别只数总数
执行 ss -s 快速获取连接总览,重点关注三类状态:
- ESTABLISHED 持续暴涨:说明连接已建好但没释放,可能是应用未 close、连接池泄漏或服务端 accept 不及时;
- CLOSE_WAIT 长期堆积:本机应用没调 close(),查 lsof -i -n -P | grep CLOSE_WAIT 找 PID,再看其日志和代码释放逻辑;
-
TIME_WAIT 过多且短时激增:不是内核参数问题,而是客户端高频短连(如 HTTP 无 keep-alive、DB 无连接复用),优先改业务逻辑而非调
tcp_tw_reuse。
查谁在连、连了多少、连得是否合理
连接暴增通常集中在少数来源,用以下命令快速下钻:
- Top 10 源 IP:ss -tn | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -10;
- 本地哪个端口最忙:ss -tn | awk '{print $4}' | cut -d: -f2 | sort | uniq -c | sort -nr;
- 查某进程打开多少 socket:ls -l /proc/[PID]/fd/ | grep socket | wc -l,对比其连接池配置(如 HikariCP 的 maxPoolSize)判断是否泄漏。
确认系统级限制是否已触顶
连接数上不去,有时不是攻击,而是被卡在底层限制:
- ulimit -n:当前进程文件描述符上限,cat /proc/[PID]/limits | grep "Max open files" 查具体值;
- net.core.somaxconn:listen 队列长度,高并发服务建议设为 65535;
- 内存压力:每个 TCP 连接内核约占 3.3KB,万级连接需百 MB 以上;用 free -h 和 vmstat 1 观察 si/so 是否非零,有 swap 就说明内存已吃紧。
结合基线与流量行为做异常判定
单看“2000 个连接”没意义,要对比常态:
- 查近一小时带宽趋势:vnstat -l;
- 比对 Nginx 日志成功请求数:awk '$9==200 {c++} END{print c+0}' /var/log/nginx/access.log;
- 若连接 90% 来自同一 C 段、User-Agent 固定、路径单一(如 /wp-login.php),基本可判定是扫描或 CC 攻击;
- 用 iftop -P 实时看哪个 IP 正在猛传数据,再用 tcpdump 抓包验证协议和行为是否合规。
不复杂但容易忽略:连接暴增引发的负载升高,常是连锁反应——比如大量 CLOSE_WAIT 导致 fd 耗尽,进而触发 “Too many open files”,再让新请求失败、重试、进一步推高连接数。所以一定要从状态入手,一层一层往下追。











