用ss快速定位僵死连接及对应进程:ss -tnop state close-wait查close_wait(对端已断、本端未关),ss -tnop state fin-wait-2查fin_wait2,ss -tnop sport=:8080按端口过滤;输出中users字段含进程pid和fd,需root权限;再用ps、lsof、cat /proc/pid/fd/fd验证进程状态与socket是否卡死。

怎么用 ss 快速找出僵死连接和对应进程
僵死连接最常见表现是卡在 CLOSE_WAIT、FIN_WAIT2 或长时间不退的 TIME_WAIT。直接跑这条命令就能定位到源头:
ss -tnop state close-wait —— 查所有 CLOSE_WAIT,这是“对端已断、本端没关”的铁证,90% 的僵死问题出在这
ss -tnop state fin-wait-2 —— 查 FIN_WAIT2,说明本端发了 FIN,但一直没等到对端的 ACK+FIN,可能对端崩溃或网络中断
ss -tnop sport = :8080 —— 指定端口过滤,避免被海量连接淹没
输出里类似 users:(("java",pid=12345,fd=102)) 这样的字段,就锁定了进程 PID 和文件描述符号。注意:必须用 root 权限运行,否则看不到 users 字段。
确认进程是否真“活着但卡住”而不是单纯退出
拿到 PID 后别急着 kill,先验证它是不是还在运行、又是不是卡在系统调用里:
-
ps -o pid,ppid,stat,wchan:20,cmd -p 12345—— 看STAT是否为S(休眠)或R(运行),再重点看WCHAN:如果显示sk_wait_data或tcp_recvmsg,说明它正阻塞在 recv 上;如果是tcp_sendmsg,大概率发不出去,对端已失联 -
lsof -p 12345 -a -iTCP—— 对比ss输出,确认 fd=102 确实对应那个僵死连接 -
cat /proc/12345/fd/102 2>/dev/null | head -c 1—— 小心尝试读取该 socket fd,若卡住无输出,基本可断定半关闭或对端消失
用 tcpkill 强行重置指定连接(不杀进程)
当确认连接已僵死、且不能重启进程时,tcpkill 是最轻量的“手术刀”:
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
sudo tcpkill -i eth0 host 192.168.1.100 and port 8080 —— 按 IP+端口匹配并发送 RST
sudo tcpkill -i eth0 port 8080 —— 更粗粒度,干掉该端口所有连接(慎用)
原理是捕获双向流量、推算 SEQ/ACK,伪造合法 RST 包发给双方。它不依赖进程状态,只操作内核 TCP 控制块(TCB),所以即使进程僵死或已退出但 TCB 残留,也能生效。
注意:tcpkill 需要 libpcap 支持,Debian/Ubuntu 装 dsniff 包,CentOS/RHEL 装 dsniff 或手动编译;另外,它只能作用于当前网卡(-i 指定),跨 VLAN 或隧道场景可能不生效。
为什么有时 tcpkill 失效?关键检查点
不是所有僵死连接都能靠 tcpkill 解决,失效往往因为底层条件不满足:
- 目标连接已完全脱离内核协议栈:比如进程异常退出后,内核已回收 TCB,但用户空间还残留 fd 句柄(
ss看不到该连接,但lsof还能列出)—— 此时只能杀进程或等内核自动清理 - 连接处于
TIME_WAIT状态且未超时:这是正常关闭后的保留状态,tcpkill不会干预;若堆积过多,应调大/proc/sys/net/ipv4/tcp_max_tw_buckets或启用net.ipv4.tcp_tw_reuse=1 - 防火墙/NAT 设备拦截了 RST 包:尤其云环境安全组默认丢弃非 ESTABLISHED 流量,RST 可能被静默丢弃,需同步检查云平台规则
- 目标主机启用了
net.ipv4.tcp_rmem或tcp_wmem极小值,导致 RST 无法入队——极少见,但高延迟链路下可能发生
真正难处理的,永远是那些 ss 里看不到、lsof 里还挂着、strace 却无系统调用记录的“幽灵连接”,它们通常意味着内核内存泄漏或驱动 bug,得查 dmesg 里的 oom 或 tcp 相关警告。










