ss —— 连接状态与端口
ss —— 连接状态与端口
分类:02 进程与网络诊断 适用:Linux(iproute2),
netstat的现代替代 一句话:查监听、查连接、查连接队列、查 TIME_WAIT,比 netstat 快得多。
1. 它解决什么问题
- 端口有没有监听?谁在监听?
- 当前有多少连接?多少
TIME_WAIT、CLOSE_WAIT? - 监听队列是否溢出(
Recv-Q/Send-Q)。 - 单条连接的拥塞窗口、RTT、重传。
2. 为什么用它替代 netstat
netstat 属于 net-tools,多数新系统默认不装,且遍历 /proc 效率低。ss 直接读内核 netlink,几万连接也是秒级。
# 习惯迁移
netstat -lntp → ss -lntp
netstat -antp → ss -antp
netstat -s → ss -s
netstat -rn → ip route (ss 不管路由)
3. 常用参数
| 参数 | 含义 |
|---|---|
-t / -u |
TCP / UDP |
-l |
只看监听 |
-a |
所有(含监听) |
-n |
不解析服务名与主机名(必加,快且准) |
-p |
显示进程(需 root) |
-s |
汇总统计 |
-i |
TCP 内部信息(RTT、cwnd、重传) |
-e |
扩展信息(socket inode、uid) |
-m |
socket 内存使用 |
-o |
定时器信息 |
-4 / -6 |
只 IPv4 / IPv6 |
-K |
强制关闭 socket(危险) |
-Z |
SELinux 上下文 |
4. 典型命令
ss -lntp # 所有 TCP 监听 + 进程(最常用)
ss -lunp # UDP 监听
ss -antp # 所有 TCP 连接
ss -s # 汇总:各状态连接数
ss -tnp # 已建立的 TCP 连接
ss -tn state established # 同上,显式状态过滤
ss -tn state time-wait | wc -l # TIME_WAIT 数量
ss -tn state close-wait # CLOSE_WAIT(应用没关)
ss -tnp dst 10.0.0.5 # 目标地址过滤
ss -tnp src 10.0.0.6 # 源地址过滤
ss -tnp dport = :3306 # 目标端口
ss -tnp sport = :80 # 源端口
ss -tnp '( dport = :80 or dport = :443 )'
ss -tnp -o # 带定时器
ss -tni # 带 RTT、cwnd、重传
ss -tm # 带内存
5. 输出怎么读
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=1234,fd=6))
ESTAB 0 0 10.0.0.5:80 10.0.0.9:53214
TIME-WAIT 0 0 10.0.0.5:80 10.0.0.9:53220
| 列 | 含义 | 判读 |
|---|---|---|
State |
连接状态 | 见下表 |
Recv-Q |
接收队列未读字节 / 监听时是已完成握手等待 accept 的连接数 | LISTEN 状态下 >0 且持续增长 = 应用 accept 不过来 |
Send-Q |
发送队列未确认字节 / 监听时是 backlog 上限 | 持续 >0 = 对端接收慢或网络拥塞 |
Local Address:Port |
本地地址 | 0.0.0.0 全部网卡,127.0.0.1 仅本地 |
Peer Address:Port |
对端 | |
Process |
进程名/PID/fd | 需 -p 且 root |
连接状态含义
| 状态 | 含义 | 异常信号 |
|---|---|---|
LISTEN |
监听 | |
ESTAB |
已建立 | |
TIME-WAIT |
主动关闭方等待 2MSL | 大量属正常;单 IP 占满端口要考虑连接池/长连接 |
CLOSE-WAIT |
对端已关,本端未关 | 大量 = 应用有 bug,没 close fd |
SYN-SENT |
已发 SYN 未收到 SYN+ACK | 多 = 目标不可达/被丢包 |
SYN-RECV |
收到 SYN 已回,未收到 ACK | 多 = SYN Flood 或半开连接堆积 |
FIN-WAIT-1/2 |
关闭中 | 长期停留 = 对端不回 FIN |
LAST-ACK |
等待最后 ACK | 有 = 关闭流程异常 |
CLOSING |
双方同时关闭 | 少见 |
6. 实战场景
6.1 端口没起来
ss -lntp | grep -w 8080
# 无输出 → 进程没监听;有输出但外部不通 → 防火墙/安全组/绑定地址问题
ss -lntp | grep 127.0.0.1 # 只绑本地,外部当然不通
6.2 连接数爆炸排查
ss -s
ss -tn state established | wc -l
ss -tn state time-wait | awk '{print $4}' | cut -d: -f1 | sort | uniq -c | sort -nr | head
按对端 IP 聚合,能直接看出是正常业务还是某个客户端在刷:
ss -tn state established '( dport = :80 )' | awk 'NR>1 {print $5}' | cut -d: -f1 \
| sort | uniq -c | sort -nr | head -20
6.3 CLOSE_WAIT 堆积
ss -tan state close-wait | head
ss -tan state close-wait | wc -l
CLOSE_WAIT 是本端没关连接,属于应用代码问题(连接泄漏、没调用 close())。调内核参数没用,改代码或重启。
6.4 监听队列溢出
ss -lnt
# Recv-Q 持续 > 0 → accept 队列堆积
LISTEN 129 511 0.0.0.0:80 0.0.0.0:*
Recv-Q=129 表示有 129 个已完成握手的连接在等 accept。持续不为 0 需:
- 提高应用并发 accept 能力(多 worker);
- 调大
net.core.somaxconn与 nginxbacklog; - 检查是否有同步阻塞逻辑拖慢 accept。
6.5 看单连接质量
ss -tni dst 10.0.0.9
ESTAB 0 0 10.0.0.5:443 10.0.0.9:51234
cubic wscale:7,7 rto:204 rtt:0.85/0.32 ato:40 mss:1448 cwnd:10 bytes_sent:10240
retrans:0/3 ...
关注:
rtt突然从 0.8 涨到 50 → 链路或对端问题;retrans非 0 且比例高 → 丢包;cwnd很小 → 拥塞窗口受限,吞吐上不去。
6.6 强制断开某连接
ss -K dst 10.0.0.99 dport = :3306 # ⚠️ 需内核支持,直接掐断
生产慎用,优先从应用层断开。
7. 常见坑
- 不加
-n:解析主机名会做 DNS 反查,几万连接时卡死。 -p看不到进程:非 root,或进程在别的 PID namespace(容器)。Recv-Q在 ESTAB 状态含义不同:是未读字节数,与 LISTEN 的 pending 连接数不是一回事。TIME_WAIT多不等于故障:它是正常的主动关闭流程。只有端口耗尽(Cannot assign requested address)才需要调tcp_tw_reuse。CLOSE_WAIT调内核参数无效:是本端应用没关,必须改代码。ss -s的TCP: n (estab m, closed k, ...)里 closed 含 TIME_WAIT,注意区分。- 容器内
ss只能看本 namespace,查宿主机用nsenter -t <pid> -n ss -lntp。 ss -K需要CONFIG_INET_DIAG_DESTROY,部分内核不支持。- 老版本无
state过滤子命令,CentOS 6 的 ss 功能很弱,升级 iproute2。
8. 速查表
ss -lntp # 监听端口(第一命令)
ss -antp # 所有 TCP
ss -s # 汇总
ss -tn state established | wc -l # 已建立数
ss -tn state time-wait | wc -l # TIME_WAIT 数
ss -tn state close-wait # CLOSE_WAIT(应用问题)
ss -tnp dst 10.0.0.5:3306 # 指定目标
ss -tni # RTT/cwnd/重传
ss -tm # socket 内存
ss -K dst <ip> # 强制断开(危险)
# 按对端聚合
ss -tn state established | awk 'NR>1{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head