从性能视角读 ss
ss 通过 netlink 直接从内核读取套接字信息,因此在连接数量很大的机器上依然能秒级返回,这一点与逐行解析 /proc 的老工具拉开差距。从性能排查的角度,它有三个用途:确认监听端口与积压情况、统计连接状态分布(尤其 TIME-WAIT 与 CLOSE-WAIT)、以及查看单个连接的队列积压与重传信息。连接数问题往往不是「连接太多」,而是「状态分布异常」。
基本信息
| 适用平台 | Linux(iproute2 套件);容器与精简镜像可能需要单独安装 |
|---|---|
| 命令语法 | ss [选项] [过滤表达式] |
| 常用选项 | -t TCP、-u UDP、-l 仅监听、-a 全部状态、-n 不解析名称、-p 显示进程、-s 汇总统计、-H 去掉表头、-e 显示扩展信息、-i 显示 TCP 内部信息(拥塞窗口、RTT、重传)、-o 显示计时器 |
| 过滤写法 | state established、state time-wait、dport = :443、sport = :8080,可在内核侧完成筛选 |
| 权限要求 | 查看进程名与 PID 需要 root,普通用户只看到自己的套接字 |
典型使用场景
- 确认服务监听:-tlnp 校验监听地址与端口是否符合预期
- 端口占用排查:启动报 Address already in use 时定位占用进程
- 状态分布分析:统计 TIME-WAIT、CLOSE-WAIT、SYN-RECV 的数量,判断压力类型
- 队列积压诊断:看监听行的 Recv-Q 是否持续非零,判断应用 accept 是否跟不上
- 慢连接分析:用 -i 查看单个连接的 RTT、重传与拥塞窗口
- 脚本采集:-H 去掉表头后输出稳定,便于解析成连接数指标
常用示例
常用示例
ss -lntp # 监听端口与进程
ss -s # 连接与内存汇总
ss -tan state established | head
ss -tan state time-wait | wc -l # TIME-WAIT 数量
ss -tan state close-wait | head # 应用未关闭的连接
ss -tn 'dport = :443' | head
ss -tnp -i 'sport = :443' | head -n 20 # 含 RTT 与重传信息
ss -H -tln | wc -l # 统计监听端口数,脚本友好
ss -lnt '( sport = :8080 )' # 定向确认某个端口状态与队列读法
| 项 | 含义 | 异常信号 |
|---|---|---|
| LISTEN | 服务正在监听 | 应有监听的服务却看不到,说明未启动或绑定了别的地址 |
| ESTAB | 已建立的连接 | 数量远高于业务预期时排查连接泄漏或未复用 |
| TIME-WAIT | 主动关闭方保留的状态 | 大量堆积说明短连接频繁,考虑连接复用 |
| CLOSE-WAIT | 对端已关闭而本端未关闭 | 持续增长通常是应用没有正确关闭连接 |
| Recv-Q(监听行) | 已完成三次握手但未被应用 accept 的连接数 | 持续非零说明应用处理不过来 |
| Send-Q(监听行) | accept 队列上限,由 backlog 决定 | 配合 Recv-Q 判断是否需要调大 backlog |
ss -s 给的是汇总视图:按协议分组的套接字总数与状态细分(已建立、被关闭、孤立、TIME-WAIT 等),以及内核为套接字分配的内存。做容量判断时它比逐条统计更快;要定位到具体进程则回到 -tlnp 与 -tnp。把 -s 的输出按固定间隔采样,就能得到连接数与状态分布的时间序列,适合在故障期间快速记录现场。
TIME-WAIT 是 TCP 的正常回收流程,不是内核 bug:主动关闭方需要等待约两倍报文最大生存时间,以保证延迟报文不干扰新连接。海量短连接场景下的优化方向是连接复用(连接池、keep-alive、HTTP/2),而不是试图消除这个状态。
把过滤交给 ss 而不是管道 grep:ss -tn state established 与 ss -tn 'dport = :443' 在内核侧筛选,既准又快;而 grep 匹配地址片段会误命中,例如过滤 443 时把 10.1.44.3 这样的地址也算进去。
读连接状态要区分「正常过渡态」与「堆积态」:等待关闭的状态短时间存在属正常,持续大量存在通常意味着对端处理慢或短连接过多。排查顺序固定为先看监听端口是否存在,再看建立连接与等待队列,最后看计数统计,按这个顺序看很少走弯路。