Linux 端口被占用排查实战:ss、lsof 与 netstat 的正确用法
一、现象:服务明明启动了,端口却连不上
线上部署时最常见的一类问题是:进程显示已经启动,但访问对应端口要么拒绝连接,要么被另一个服务“抢”了流量。多数情况下这不是代码问题,而是端口被占用、监听地址不对,或者残留的 TIME_WAIT 状态太多。排查这类问题,关键是把“谁在监听这个端口”查清楚。
二、第一步:用 ss 查看监听状态
ss 是 netstat 的现代替代品,读取内核 socket 信息,速度快得多。最常用的一条命令是:
ss -tlnp
参数含义:t 表示 TCP,l 表示处于 LISTEN 状态,n 表示不做域名解析,p 表示显示持有该 socket 的进程。输出里会直接给出本地地址、端口、进程名和 PID,一眼就能看出 80 端口到底被 nginx 还是某个遗留的 java 进程占着。如果只想看某个端口,可以这样过滤:
ss -tlnp 'sport = :8080'
注意 -p 需要 root 权限才能看到其他用户的进程信息,普通用户执行时进程名会显示为空。
三、第二步:用 lsof 精确定位进程
如果想知道“这个进程到底打开了哪些文件描述符”,lsof 更合适。按端口查:
lsof -i :8080
输出包含 COMMAND、PID、USER、FD、TYPE、DEVICE、SIZE/OFF、NODE、NAME 等列,其中 NAME 会显示具体的监听地址,比如 *:8080 或 127.0.0.1:8080。只监听 127.0.0.1 是很常见的坑:服务本身没问题,但只绑定回环地址,外部自然访问不到。遇到这种情况,要检查应用配置里的 bind 地址,而不是怀疑防火墙。
四、第三步:老系统上的 netstat
一些老发行版或精简镜像里没有 ss,可以用 netstat:
netstat -tlnp | grep 8080
功能类似,但在连接数很多时明显更慢,因为它要遍历 /proc 下的全部信息。生产环境建议优先用 ss。
五、几个高频坑
第一,TIME_WAIT 堆积。短连接较多的服务会出现大量 TIME_WAIT,虽然一般不阻塞监听,但会占用本地端口资源。可以通过调整 net.ipv4.tcp_tw_reuse 缓解,但不要盲目开启 tcp_tw_recycle,它在 NAT 环境下会造成连接异常。第二,端口复用。SO_REUSEADDR 允许快速重启后重新绑定端口,但两个进程不能同时监听同一地址端口,除非使用了 SO_REUSEPORT。第三,容器端口映射。容器内服务监听 0.0.0.0:8080,宿主机映射到 8080,但如果容器内只监听 127.0.0.1,宿主机转发进来就会失败。第四,防火墙与安全组。ss 显示端口在监听,不代表外部可达,还要确认 iptables、firewalld 以及云平台安全组。
六、一套可复用的排查顺序
建议按这个顺序走:先用 ss -tlnp 确认端口是否在监听、由谁监听;再用 lsof -i :端口 确认监听地址和进程;然后从本机 curl 127.0.0.1:端口 排除应用层问题;接着从另一台机器 curl 公网地址,验证网络与安全组;最后看应用日志和内核参数。按这个顺序,绝大多数“端口不通”的问题都能在几分钟内定位。
把这几条命令固化成习惯,比记住一堆参数更有用。真正的排查能力,来自对每一层(进程、监听地址、网络、安全组)边界的清楚认识。
- 点赞
- 收藏
- 关注作者
评论(0)