查tcp连接状态分布应优先使用netstat -s或ss -s获取内核原始统计,重点关注close-wait异常堆积(需ss -tanp定位pid),time_wait高需先验证端口耗尽,单进程socket泄漏用lsof -itcp -stcp:close_wait分析。

查 TCP 连接状态分布用 netstat -s 或 ss -s
直接看全局连接状态计数,netstat -s 和 ss -s 是最轻量、最权威的入口。它们输出的是内核网络栈的原始统计,不依赖进程权限,也不受连接数上限限制。
关键不是“有多少连接”,而是“哪些状态在异常堆积”:
-
netstat -s | grep -A 5 "Tcp:"能看到active connections openings(主动建连)、passive connection openings(被动建连)、failed connection attempts(建连失败)等基础指标 -
ss -s输出更简洁,第一行就带总连接数和各状态汇总,例如TCP: time_wait 12456、CLOSE-WAIT 892 - 注意区分大小写:
CLOSE-WAIT是标准写法,close_wait在 awk/grep 中常忽略大小写,但状态字段本身是大写
定位 CLOSE-WAIT 连接归属进程必须用 ss -tanp
CLOSE-WAIT 多意味着本机应用收到对方 FIN 后没调 close(),这是代码级泄漏,不能靠调参解决。必须锁定 PID 才能追根溯源。
执行 ss -tanp state close-wait(需 root 权限),输出每行含:源 IP:端口、目标 IP:端口、状态、PID/程序名。常见陷阱:
- 没加
-p就看不到进程,白查;加了但没 root 权限,PID 列显示为-或报 permission denied - 某些容器或 systemd 服务会显示为
dockerd或systemd,得再用ps -p <pid> -o comm=,cmd=</pid>看真实命令路径 - 如果同一 PID 下有大量
CLOSE-WAIT,优先检查该进程的日志(如journalctl -u xxx --since "10 minutes ago")和连接池配置
TIME_WAIT 高是否真影响服务?先验证端口耗尽再行动
TIME_WAIT 本身不是问题,Linux 默认允许复用 TIME_WAIT 套接字(net.ipv4.tcp_tw_reuse = 1 且 net.ipv4.tcp_timestamps = 1)。真正卡住的是“本地端口不够用”。
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
验证方法分两步:
- 查当前可用端口范围:
cat /proc/sys/net/ipv4/ip_local_port_range(默认通常是32768 60999,共约 28K 端口) - 统计已用本地端口频次:
ss -ant | awk '{print $4}' | cut -d':' -f2 | sort | uniq -c | sort -nr | head -5—— 如果前几名全是同一端口(比如 52043 出现上万次),说明短连接风暴集中打向单一后端,不是系统瓶颈,是业务设计问题 - 若
Cannot assign requested address错误频繁出现,且ss -ant | wc -l接近端口上限,才考虑调优,否则别碰tcp_tw_reuse
用 lsof 查单个进程的 socket 泄漏细节
当确认某个 PID 的 CLOSE-WAIT 持续增长,lsof -iTCP -sTCP:CLOSE_WAIT -n -P -p <pid></pid> 可列出该进程所有未关闭的 TCP socket,包括远端地址、inode 号、文件描述符编号。
这个输出能帮你判断泄漏模式:
- 远端 IP 高度集中 → 某个下游服务响应慢或不发 FIN,上游没设超时
- 远端 IP 分散但 FD 编号持续递增 → 应用层每次 new connection 都没 close,典型忘记 defer 或 try/finally
- 同一 inode 出现多次 → 可能是连接复用失效(如 HTTP client 未启用 keepalive)
真正难缠的不是状态数字本身,而是那些 CLOSE-WAIT 连接背后僵死的 goroutine、Java thread 或 Python asyncio task——它们不占 CPU,但锁着 fd、内存和连接上下文,日积月累才拖垮服务。










