在现代分布式系统、微服务架构和高并发应用环境中,网络连接的状态管理直接关系到服务的稳定性、性能与安全性。无论是排查数据库连接池耗尽、识别异常客户端行为,还是优化负载均衡策略,理解并实时监控特定端口上的 TCP 连接状态分布都是一项核心运维技能。
本文将带你深入剖析一个强大而灵活的命令组合:
ss -tn state all | grep ':<PORT>' | awk '{print $1}' | sort | uniq -c | sort -nr
一、为什么需要分析特定端口的连接状态?
TCP 连接在其生命周期中会经历多个状态(如 ESTAB、TIME-WAIT、CLOSE-WAIT、LISTEN 等)。不同状态的数量分布能揭示以下关键信息:
| 状态 | 含义 | 异常信号 |
|---|---|---|
| ESTAB | 已建立的活跃连接 | 数量突增可能表示流量激增或 DDoS |
| TIME-WAIT | 主动关闭后等待 2 倍的 MSL(Maximum Segment Lifetime,最大报文段生存时间) | 大量堆积可能消耗端口资源 |
| CLOSE-WAIT | 对端已关闭,本地未调用 close() | 应用未正确释放连接,存在内存/文件描述符泄漏风险 |
| FIN-WAIT-1/2 | 正在关闭流程中 | 若长期存在,可能网络中断或对端无响应 |
| LISTEN | 服务正在监听 | 通常只有一个,若缺失说明服务未启动 |
通过统计这些状态的分布,我们可以快速判断服务是否健康、是否存在资源瓶颈,甚至发现潜在的安全攻击。
二、命令详解:从原始数据到可视化洞察
我们以通用形式展开分析:
ss -tn state all | grep ':<PORT>' | awk '{print $1}' | sort | uniq -c | sort -nr
· 提示:将 <PORT> 替换为你关心的实际端口号,例如 80、443、5432、9092 等。
第一步:ss -tn state all
· ss(Socket Statistics)是 iproute2 工具包的一部分,比传统的 netstat 更快、更高效。
· -t:仅显示 TCP 套接字。
· -n:禁用 DNS 和服务名解析,直接以 IP 和端口号显示(提升速度,避免解析阻塞)。
· state all:包含所有 TCP 状态(默认只显示非 LISTEN 状态)。
输出示例(简化):
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 192.168.1.10:80 203.0.113.5:54321
TIME-WAIT 0 0 192.168.1.10:80 203.0.113.6:12345
LISTEN 0 128 0.0.0.0:80 0.0.0.0:*
CLOSE-WAIT 0 0 192.168.1.10:80 203.0.113.7:65432
第二步:grep ':<PORT>'
筛选出本地或远程涉及目标端口的连接。
· 注意:此写法会同时匹配
1.本地监听端口(如 0.0.0.0:80)
2.本地发起的连接(如 192.168.1.10:54321 → remote:80)
3.远程连接到本机(如 192.168.1.10:80 ← client:12345)
因此,它适用于“与该端口相关的所有连接”场景。但如果你只想看本机监听该端口并接收的连接,建议使用更精确的过滤方式(见下文“进阶技巧”)。
第三步:awk '{print $1}'
提取第一列——即 TCP 连接状态(ESTAB、TIME-WAIT 等)。
第四步:sort | uniq -c
· sort:将状态名称排序,使相同状态相邻;
· uniq -c:统计每种状态出现的次数,并在行首显示计数。
输出示例:
120 TIME-WAIT
45 ESTAB
3 CLOSE-WAIT
1 LISTEN
第五步:sort -nr
· -n:按数值排序;
· -r:逆序(从大到小)。
最终结果按连接数量降序排列,便于快速识别主导状态。
三、实战示例:分析不同服务的连接状态
示例 1:Web 服务器(端口 80)
ss -tn state all | grep ':80' | awk '{print $1}' | sort | uniq -c | sort -nr
典型输出:
2000 TIME-WAIT
300 ESTAB
1 LISTEN
→ 表明 Web 服务处理大量短连接,TIME-WAIT 较高属正常现象,但若持续增长需关注端口耗尽风险。
示例 2:PostgreSQL 数据库(端口 5432)
ss -tn state all | grep ':5432' | awk '{print $1}' | sort | uniq -c | sort -nr
若看到:
100 CLOSE-WAIT
50 ESTAB
→ 高 CLOSE-WAIT 是危险信号!说明应用未正确关闭数据库连接,可能导致连接池耗尽。
示例 3:Kafka Broker(端口 9092)
ss -tn state all | grep ':9092' | awk '{print $1}' | sort | uniq -c | sort -nr
→ 理想情况应有大量 ESTAB(长连接),极少 TIME-WAIT。若出现大量 FIN-WAIT-2,可能消费者异常断开。
四、进阶技巧:更精准、更安全的过滤方式
1. 仅匹配本地监听端口的连接(推荐)
使用 ss 内置的过滤语法,避免 grep 的模糊匹配:
ss -tn state all '( dport = :<PORT> or sport = :<PORT> )'
或者更严格地只看本机作为服务端的连接:
ss -tn state all 'sport = :<PORT>'
· 注意:ss 的过滤语法使用 : 表示端口,且支持逻辑运算符。
2. 排除 LISTEN 状态(专注活跃连接)
有时我们只关心已建立的连接:
ss -tn state established | grep ':<PORT>' | wc -l
或统计非 LISTEN 状态:
ss -tn state all | awk -v port="<PORT>" '
$4 ~ /:[0-9]+$/ {
split($4, a, ":"); local_port = a[2]
}
$5 ~ /:[0-9]+$/ {
split($5, b, ":"); remote_port = b[2]
}
(local_port == port || remote_port == port) && $1 != "LISTEN" { print $1 }
' | sort | uniq -c | sort -nr
3. 实时监控(配合 watch)
watch -n 2 "ss -tn state all 'sport = :80' | awk '{print \$1}' | sort | uniq -c | sort -nr"
每 2 秒刷新一次,观察状态变化趋势。
五、常见误区与注意事项
· grep ':80' 会误匹配端口 8080、180 等
→ 解决方案:使用正则边界 \b 或 ss 内置过滤器。
· ss 默认不显示 LISTEN 状态
→ 必须加上 state all 或单独用 ss -ltn 查看监听。
· 大量 TIME-WAIT 不一定是问题
→ 在高并发短连接场景下是正常的,可通过 net.ipv4.tcp_tw_reuse=1 优化。
· 容器环境需进入对应网络命名空间
→ 使用 nsenter -t <PID> -n ss ... 或在容器内执行。
六、总结
通过组合 ss、grep、awk、sort 和 uniq,我们构建了一个轻量级但功能强大的 TCP 连接状态分析工具。它无需安装额外软件,适用于几乎所有现代 Linux 发行版,并能灵活适配任意端口。
评论