ss —— 查看套接字/网络连接状态(netstat 的现代替代)
这个工具是做什么的
ss = socket statistics,直接从内核读取(不像 netstat 那样遍历 /proc/net),在连接数多时快几个数量级。用来排查:连接数暴涨、端口被谁占、TCP 状态堆积(TIME-WAIT/CLOSE-WAIT)、连接泄漏、握手异常。
可以回答什么问题
| 问题 | 怎么用 |
|---|---|
| 系统有多少个 TCP 连接?各状态分别多少? | ss -s 看汇总 |
| 哪个进程监听了某端口?端口被占了吗? | ss -tlnp | grep :8080 |
| TIME-WAIT 连接多不多(短连接问题)? | ss -tan state time-wait | wc -l |
| CLOSE-WAIT 堆积了吗(连接泄漏)? | ss -tan state close-wait:堆积 = 程序忘了 close |
| 接收队列积压了吗(应用处理不过来)? | Recv-Q 持续增大 |
| 某进程连了哪些地址? | ss -tanp | grep <PID> |
| TCP 重传、RTT 多少? | ss -ti 看内部信息 |
数据来源
- 来源接口:内核 netlink 的
NETLINK_SOCK_DIAG(inet_diag)接口,直接向内核批量查询套接字表。 - 采集方式:一次 netlink 请求即可拿到全部匹配的套接字,而 netstat 是逐行解析
/proc/net/tcp等文本文件。 - 由此决定的特性:连接数上万/十万时,
ss比 netstat 快几个数量级(少了逐行文本解析);且-i/-e/-m能拿到/proc/net文本给不出的内核内部信息(rtt、cwnd、内存占用等)。
bash
# iproute2 包,多数系统自带
yum install iproute / apt install iproute2一、参数速记
t=TCP u=UDP x=Unix域 l=只看 LISTEN a=全部(含监听) n=数字不解析(快)p=显示进程(需 root) s=汇总 i=TCP 内部信息 e=扩展信息 m=内存用量 o=计时器。
二、常用组合
bash
ss -tan # 所有 TCP 连接(数字形式)
ss -tanp # + 占用连接的进程/PID(root 才看得全)
ss -tlnp # 所有监听中的 TCP 端口 + 进程(查服务起没起/端口冲突)
ss -tunlp # TCP+UDP 所有监听端口 + 进程
ss -uanp # UDP 全部
ss -s # 汇总:各状态连接总数,快速看规模
ss -tanp | grep <PID> # 某进程建立/监听了哪些连接三、输出与字段
bash
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
ESTAB 0 0 10.0.0.2:22 10.0.0.9:53344 users:(("sshd",pid=1234,fd=3))
LISTEN 0 128 0.0.0.0:8080 0.0.0.0:* users:(("java",pid=5678,fd=42))| 列 | 含义 | 判读 |
|---|---|---|
State | TCP 状态 | 见下表 |
Recv-Q | 接收队列积压字节 | LISTEN 态下是全连接队列当前长度;ESTAB 下是已收到但应用还没 read 的数据——持续大 = 应用消费不过来 |
Send-Q | 发送队列 | LISTEN 态下是全连接队列上限(backlog);ESTAB 下是已发但对端还没 ACK 的数据——持续大 = 对端慢/网络拥塞 |
Local/Peer Address:Port | 本端/对端地址 | * 表示任意 |
Process | 占用的进程(需 -p + root) | 定位归属 |
四、按条件过滤
bash
ss -tan state established # 只看已建立
ss -tan state time-wait # 只看 TIME-WAIT
ss -tan state syn-recv # 半连接(SYN flood 时暴涨)
ss -tanp '( dport = :3306 or sport = :3306 )' # 按端口(如 MySQL)
ss -tanp dst 10.0.0.5 # 到某目标 IP
ss -tanp dst 10.0.0.0/24 # 到某网段
ss -tin # -i 显示 rtt、cwnd、重传等 TCP 内部信息
ss -tm # -m 看每个 socket 的内存占用
ss -to # -o 显示 keepalive/重传计时器五、TCP 状态与排查
| 状态 | 含义 | 排查要点 |
|---|---|---|
LISTEN | 监听中 | 服务没起来先确认这个在不在 |
ESTAB | 已建立 | 连接数暴涨 → 查是否连接泄漏、连接池配置 |
TIME-WAIT | 主动关闭方等 2MSL | 大量堆积 = 短连接过多:改长连接/连接池,或调 net.ipv4.tcp_tw_reuse、加大端口范围 ip_local_port_range |
CLOSE-WAIT | 对端已关,本端没 close() | 堆积 = 程序 BUG:代码收到 EOF 后忘了关 socket,导致 fd 泄漏,最终 EMFILE。这是最该警惕的状态 |
SYN-SENT | 本端发了 SYN 等回应 | 大量堆积 → 连不上对端(对端挂了/防火墙丢包) |
SYN-RECV | 收到 SYN 等 ACK | 大量堆积 → 可能 SYN flood,或全连接队列满 |
FIN-WAIT-1/2 | 关闭流程中 | 大量 FIN-WAIT-2 → 对端不发 FIN,可能对端有 bug |
六、典型场景
bash
ss -s # 先看总量,连接是否异常多
ss -tan state close-wait | wc -l # CLOSE-WAIT 计数,排查连接泄漏
ss -tan state time-wait | wc -l # TIME-WAIT 计数,判断短连接压力
ss -tlnp | grep :8080 # 8080 被哪个进程占(端口冲突)
ss -tanp | grep -c ESTAB # 当前建立的连接总数
watch -n1 'ss -s' # 持续观察连接规模变化七、关键指标速查
| 指标 | 缩写/英文 | 命令 | 正常值 | 异常信号 |
|---|---|---|---|---|
| 接收队列积压 | Recv-Q | ss -tanp | 0 | 持续 > 0 → 应用消费跟不上 |
| 发送队列积压 | Send-Q | ss -tanp | 0 | 持续 > 0 → 对端窗口关闭/拥塞 |
| LISTEN backlog 当前 | Recv-Q (LISTEN) | ss -tlnp | 0 | > 0 → 全连接队列积压 |
| LISTEN backlog 上限 | Send-Q (LISTEN) | ss -tlnp | somaxconn | 太小 → 高并发下 SYN 被丢弃 |
| ESTABLISHED 总数 | Estab Count | ss -s | 视业务 | 接近 somaxconn → 受限 |
| TIME-WAIT 数 | TIME-WAIT Count | ss -tan state time-wait | wc -l | < 1000 | > 万 → 短连接过多 |
| CLOSE-WAIT 数 | CLOSE-WAIT Count | ss -tan state close-wait | wc -l | 0 或很少 | 堆积 → 连接泄漏(程序忘 close) |
| SYN-RECV 数 | SYN-RECV Count | ss -tan state syn-recv | wc -l | 很少 | 暴涨 → SYN flood 攻击或全连接队列满 |
| RTT | Round-Trip Time | ss -ti | < 10ms(同机房) | 几百 ms → 跨地域/拥塞 |
| TCP 重传 | Retrans | ss -ti | grep retrans | 0 | > 0 → 丢包/网络质量差 |
| 拥塞窗口 | Cwnd | ss -ti | grep cwnd | 视 RTT | ssthresh 被压低 → 曾发生拥塞 |
| Socket 内存占用 | Socket Mem | ss -tm | 视场景 | 持续增长 → socket buffer 泄漏 |
指标体系全景图

八、常见排查方法与分析
8.1 CLOSE-WAIT 堆积 → 连接泄漏(最危险)
bash
ss -tan state close-wait # 堆积大量连接
→ ss -tanp state close-wait | awk '{print $NF}' | sort | uniq -c
→ 找到占用的进程/PID
→ lsof -p <PID> | wc -l → 看 fd 总量
→ 检查代码:对端 FIN 后是否忘了 close()8.2 TIME-WAIT 过多 → 短连接
bash
ss -s → timewait 数万
→ ss -tan state time-wait | head → 看主要涉及哪些端口
→ 短连接过多(每次请求建立新连接而非复用)
→ 改为长连接/连接池
→ 调内核参数:tcp_tw_reuse=1, ip_local_port_range8.3 Recv-Q 积压 → 应用处理不过来
bash
ss -tanp → Recv-Q 持续 > 0
→ 数据已到达内核,但应用程序没调用 read()/recv()
→ top 看进程 CPU 是否打满
→ strace -e trace=read,recvfrom -p <PID> 看是否在调用8.4 连接数暴涨定位
bash
ss -s → 连接总数异常多
→ ss -tan state established | awk '{print $6}' | sort | uniq -c | sort -rn
→ 看连接的主要目标 → 可能是某个下游服务慢导致堆积
→ 或看是否有连接泄漏(增长不回落)8.5 网络延迟/重传定位
bash
ss -ti → 看 rtt 和 retrans
→ rtt 高 → 链路上有延迟(跨机房/拥塞)
→ retrans 非零 → 丢包
→ sar -n ETCP 1 → 看全系统重传速率
→ ethtool -S <网卡> → 查硬件层丢包九、交叉引用
- 进程 fd 检查:lsof(ss 看到连接多 → lsof 确认 fd 数)
- 网络中断:mpstat
%soft(Recv-Q 高 + 软中断偏单核) - 数据源:procfs §三(/proc/net/* 和 netlink 接口)
- 抓包分析:tcpdump(比 ss 更底层的包级分析)
十、与其他工具联动
- 软中断
%si高 / 网络卡顿:ss -s看连接规模 →mpstat -P ALL 1看%soft是否压在某个核 →cat /proc/softirqs看NET_RX/NET_TX增长 → 考虑网卡多队列/RPS。 Recv-Q持续积压:应用处理不过来,回到 top/perf 看应用为何慢。- fd 耗尽(EMFILE):
ss数连接 +lsof -p <PID>数 fd,交叉确认是不是连接没关。
总结
ss 是看 socket/连接状态的现代工具(netstat 的高速替代):ss -lntp 列监听端口与进程、-s 看连接总数汇总、-tan state established 按 TCP 状态过滤、-ti 看每条连接的 RTT 与重传;排查时 Send-Q/Recv-Q 积压是关键——Recv-Q 持续堆积说明数据到了内核但应用没 read(应用处理不过来,回 top/perf 查应用),连接数暴涨用 ss -tan | awk 统计对端地址找下游堆积或连接泄漏,retrans 非零转 sar -n ETCP/ethtool -S` 查丢包,fd 耗尽用 ss 数连接 + lsof 数 fd 交叉确认。