【无标题】

Linux ss命令排查指南

一、前言:为什么你应该忘掉netstat

如果你还在用 netstat -antp 排查服务器端口占用,是时候切换到 ss 了。

ss(Socket Statistics)是 iproute2 工具包中的一员,能直接查询内核 socket 统计信息,速度远超 netstat。两者的性能差异在遇到高并发连接时极其明显------一台十万连接的服务器,netstat 可能卡死半天出不来结果,ss 却可以秒出。

简单来说:netstat 读 /proc 遍历所有 pid,ss 直接调用 netlink 跟内核对话。路径不同,效率天差地别。

本文从日常使用的角度出发,把参数和排查场景串起来,读完你可以直接在工作中用起来。


二、基础三连:最常用的参数组合

2.1 查看所有 TCP 连接

bash 复制代码
ss -tan
  • -t:只看 TCP
  • -a:所有状态(包括 LISTEN 和 非 LISTEN)
  • -n:以数字形式显示端口,不做 DNS 反向解析(生产环境必带,否则卡死

输出示例:

复制代码
State      Recv-Q Send-Q Local Address:Port   Peer Address:Port  Process
LISTEN     0      128    0.0.0.0:22           0.0.0.0:*
ESTAB      0      0      192.168.1.10:22      10.0.0.5:51824
TIME-WAIT  0      0      192.168.1.10:443     10.0.0.6:60231

2.2 只看监听端口

bash 复制代码
ss -tln
  • -l:只看 LISTEN 状态

这一条是日常开发中最常用的命令------"我这个服务到底起来了没有?端口有没有被占用?"一行搞定。

2.3 显示进程信息

bash 复制代码
ss -tanp
  • -p:显示占用该 socket 的进程名和 PID

这是排错利器。端口被哪个进程占了,一眼就知道。


三、状态过滤:精准定位连接问题

TCP 连接有多种状态,生产环境排查时,我们通常只关心特定状态的连接。

3.1 查看所有 TIME-WAIT 连接

bash 复制代码
ss -tan state time-wait

state 参数支持的 TCP 状态有:

establishedsyn-sentsyn-recvfin-wait-1fin-wait-2time-waitclosedclose-waitlast-acklistenclosing

3.2 实战场景:服务端口被占用

你的 Java 服务启动报 Address already in use,快速查谁在占用 8080:

bash 复制代码
ss -tlnp | grep :8080
# 或者更精准
ss -tlnp 'sport = :8080'

输出会直接告诉你 PID 和进程名,接着 kill 就行。

3.3 实战场景:统计各状态连接数

服务器上连接池突然满了,先看TIME-WAIT和CLOSE-WAIT各有多少:

bash 复制代码
ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn

输出类似:

复制代码
    324 ESTAB
    156 TIME-WAIT
     12 LISTEN
      3 CLOSE-WAIT
      1 State

如果 CLOSE-WAIT 数量很高,说明你的应用没有正确关闭连接(通常是代码里忘了调 close()),这是应用层bug,不是网络问题。

如果 TIME-WAIT 很高(比如上千),说明短连接过多,可以考虑开启 tcp_tw_reuse

3.4 实战场景:查看指定端口的连接数

想知道 Nginx 的 443 端口扛了多少连接:

bash 复制代码
ss -tan 'sport = :443' | wc -l
# 或者只看 ESTABLISHED
ss -tan state established 'sport = :443' | wc -l

四、进阶过滤:源/目的地址组合

ss 的过滤表达式非常强大,格式为 expr [ expr ...],支持的 key 包括 sportdportsrcdst 等。

4.1 看某个客户端连了多少连接

怀疑某个 IP 在疯狂请求你的服务:

bash 复制代码
ss -tan state established 'dport = :443' | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head

4.2 看本机到某个远程地址的连接

排查服务调用外部 API 的情况:

bash 复制代码
ss -tan 'dst 10.0.0.100 and dport = :3306'

这条命令能直接定位到本机哪些进程在连接目标 MySQL。

4.3 过滤与统计组合

查看本机 6379(Redis)端口被哪些客户端连接:

bash 复制代码
ss -tan 'sport = :6379 or dport = :6379'

五、UDP 也别忘了

ss 不只管 TCP,UDP 也一样:

bash 复制代码
# 所有 UDP socket
ss -uan

# 只看监听的 UDP
ss -uln

# 带进程信息
ss -uanp

排查 DNS 问题时(53端口),可以这样看:

bash 复制代码
ss -uanp 'sport = :53 or dport = :53'

六、Unix Domain Socket

容器化环境里,php-fpm、MySQL、Docker daemon 经常通过 Unix socket 通信:

bash 复制代码
ss -xln          # 只看 LISTEN 的 Unix socket
ss -xanp         # 全部 Unix socket 带进程信息

排查 MySQL 时,除了看 TCP 3306,也别忘了看 /var/run/mysqld/mysqld.sock 在不在、有没有进程在听。


七、实战案例合集

案例一:线上服务假死------大量 CLOSE-WAIT

现象:用户反馈页面打不开,Nginx 返回 502。

排查过程

bash 复制代码
# 1. 看服务端口还在不在
ss -tlnp | grep :8080
# 端口在,进程在

# 2. 看连接状态分布
ss -tan state established 'sport = :8080' | wc -l
ss -tan state close-wait 'sport = :8080' | wc -l
# CLOSE-WAIT 有 2000+,ESTABLISHED 只有几十

结论 :下游服务已经关闭了连接(发了 FIN),但本端应用没有调用 close(),导致大量 CLOSE-WAIT,文件描述符耗尽,新请求无法处理。

修复方向:检查 HTTP 客户端的连接关闭逻辑,确认 response body 是否每次都正确关闭。


案例二:端口被占用但 lsof 找不到

现象 :启动服务报 Address already in use,但 lsof -i:8080 查不到。

排查

bash 复制代码
ss -tlnp 'sport = :8080'

如果 ss 能看到 LISTEN 但 lsof 看不到,常见原因:

  • Docker 端口映射残留(docker-proxy 进程)
  • 容器里的进程在监听
  • 内核态模块绑定的端口(比如某些 eBPF 程序)

可以用 ss -tlnpe-e 扩展信息)看看更多细节。


案例三:TCP 重传排查

bash 复制代码
ss -tine

-i 显示 TCP 内部信息,包括 RTT、重传次数、拥塞窗口等。这个输出比较长,但排查丢包问题时非常有用。

关键字段:

  • retrans:重传次数,持续增长说明链路丢包严重
  • rtt:往返延迟
  • cwnd:拥塞窗口大小,如果很小说明 TCP 认为网络拥堵
  • unacked:已发送未确认的包数量

可以针对特定连接看:

bash 复制代码
ss -tine 'sport = :443 and dst 10.0.0.5'

案例四:内存占用分析

bash 复制代码
ss -tam

-m 显示 socket 内存使用情况:

复制代码
skmem:(r0,rb37440,t0,tb87040,f0,w0,o0,bl0,d0)
  • rb:接收缓冲区大小
  • tb:发送缓冲区大小
  • r:已使用的接收缓冲区
  • t:已使用的发送缓冲区

如果 r 持续接近 rb,说明应用读取速度跟不上接收速度,可能需要调整 net.core.rmem_max


八、参数速查表

参数 含义
-t TCP
-u UDP
-x Unix Domain Socket
-l 仅 LISTEN
-a 所有 socket
-n 不解析服务名/DNS(生产必带)
-p 显示进程信息
-e 扩展信息
-i TCP内部信息(RTT/重传/窗口)
-m socket内存使用
-s 汇总统计
-r 解析主机名
-4 仅 IPv4
-6 仅 IPv6
-K 关闭慢启动探测
state 按TCP状态过滤
sport/dport 源/目的端口过滤
src/dst 源/目的地址过滤

九、常用组合记忆法

不用死记硬背,记住这几个场景就行:

场景 命令
我服务起了没 ss -tlnp
谁在连我的服务 ss -tan 'sport = :端口'
端口被谁占了 ss -tlnp 'sport = :端口'
我的服务在连谁 ss -tan 'dport = :端口'
连接数统计 ss -s
TIME-WAIT多不多 `ss -tan state time-wait
网络是不是在丢包 ss -tine
内存是不是不够 ss -tam

十、总结

ss 是 Linux 系统工程师的瑞士军刀之一。它的优势在于:

  1. :直接与内核通信,高并发场景下几乎无感
  2. 表达式过滤:不用像 netstat 那样管道给 grep awk,ss 自带强大的过滤语法
  3. 信息全:TCP 内部状态、内存使用、重传统计一应俱全

日常排查记住三板斧:ss -tlnp 看监听、ss -tan 看连接全貌、ss -tine 看 TCP 细节,基本能覆盖 80% 的网络排查场景。

剩下的 20%,靠你对 TCP 状态机的理解和表达能力把 statesportdport 组合出花样来。


本文写于 2026 年 6 月,基于 Linux 内核 5.x/6.x 环境。不同发行版的 ss 版本可能有细微差异,以 ss --version 为准。

相关推荐
似水এ᭄往昔1 小时前
【Linux系统编程】--进程概念
linux·运维·服务器
小徐敲java2 小时前
Linux读取串口实时数据
linux·运维·服务器
zhangfeng11333 小时前
车载gpu 飞地 只保存密钥 不保存 权重 Orin确实有TEE安全飞地(TSEC/OP-TEE)
服务器·网络·人工智能·安全·transformer·芯片
keyipatience3 小时前
25.Linux静态动态库全解析
linux·运维·服务器
飞Link3 小时前
【TCP\UDP与可靠传输】UDP 的“简单粗暴”和它真正适用的场景
网络·网络协议·tcp/ip·udp
weixin_520649873 小时前
通信与TCP核心知识
服务器·网络·tcp/ip
开开心心_Every3 小时前
多连接方式的屏幕共享工具推荐
运维·服务器·pdf·电脑·excel·tornado·dash
AskHarries3 小时前
Workspace:文件系统、项目上下文和执行边界
java·服务器·前端
liulilittle3 小时前
我从 BBRv1 到 KCC 的思考
网络·c++·tcp/ip·计算机网络·tcp·bbr·通信