Linux 排查端口占用的 5 种方法:从 ss 到 /proc 的实战清单
排查端口占用几乎是 Linux 上最日常的一次操作:服务起不来,日志里只有一句 bind: address already in use,接下来就是确认这个 8080 到底被谁占了。可用工具不少,但真正好用的只有几条命令。下面按实用性排序,并补上容器和 IPv6 两个最常见的高频坑。
一、ss:现代发行版的首选
ss 属于 iproute2,是 netstat 的替代品。它直接读取内核 socket 表,比 netstat 逐个遍历 /proc 快得多,输出也更干净:
ss -tlnp | grep 8080
参数含义很固定:-t 只看 TCP,-l 只看监听,-n 不做域名解析,-p 显示进程。最后一列 users:(("nginx",pid=1234,fd=6)) 就是答案。
如果只关心某个端口,可以直接把过滤条件交给 ss,省掉管道:
ss -tlnp 'sport = :8080'
二、lsof:从端口反查进程
lsof -i:8080
输出 USER、PID、COMMAND、NAME 一应俱全,还能区分本机监听(LISTEN)与已建立连接(ESTABLISHED),排查「谁在连我的服务」时特别好用。它的短板是精简镜像里通常没有,需要额外安装 lsof 包。
三、fuser:一条命令直达
fuser -n tcp 8080 # 打印占用者的 PID
fuser -k -n tcp 8080 # 直接杀掉
生产环境慎用 -k,先看清 PID 再动手,避免误杀正在承载流量的进程。
四、netstat:老系统的兜底
netstat -tunlp | grep 8080
在 CentOS 7 之前以及部分精简系统中,它仍是唯一选择。它依赖 net-tools,很多新镜像默认不装,属于能用但不必首选。
五、什么工具都没有时:直接读 /proc
容器镜像里 ss、lsof、netstat 常常一个都没有,此时可以手工解析:
- 确认端口是否被监听,8080 的十六进制是 1F90:
grep -i ':1F90' /proc/net/tcp
- 记下输出里的 inode,再反查持有该 socket 的进程:
for p in /proc/[0-9]*; do
ls -l $p/fd 2>/dev/null | grep -q 'socket:\[12345\]' && echo $p
done
把 12345 换成上一步拿到的 inode 即可。步骤繁琐,但没有外部依赖,是最可靠的兜底手段。
两个高频坑
只监听在 IPv6 上。 ss 默认同时展示 v4 与 v6,而不少程序(Node 服务、部分 Java 应用)只 bind 了 ::。用 netstat -tlnp 默认只看 IPv4,会得出「没人占用」的错误结论。加 -6 或直接看 ss 的全量输出即可避免。
容器里的进程在宿主机上不可见。 在宿主机执行 ss -tlnp 时,容器内进程的 PID 属于另一个命名空间,-p 一列可能为空或显示不出名字。正确做法是进入容器排查,或用 nsenter -t <容器 init 的 PID> -n ss -tlnp 切到容器的网络命名空间再看。
小结
日常顺序可以固化为:ss -tlnp 定位,lsof -i:端口 补上下文,确实需要强杀再 fuser -k。这三条记住,九成的端口问题五分钟内能收尾;剩下的一成通常是权限(非 root 看不到 -p 的进程信息)或命名空间问题,知道原因就不会慌。
- 点赞
- 收藏
- 关注作者
评论(0)