端口被占了服务起不来?ss + lsof 三分钟定位谁在用这个端口

举报
yd_260072176 发表于 2026/11/07 11:14:15 2026/11/07
【摘要】 新服务一启动就报错 Address already in use,或者反过来,服务明明跑着,浏览器却连不上——十次有九次是端口出了问题:要么被别的进程占了,要么服务根本没监听在你以为的那个端口上。ss 和 lsof 是每台 Linux 服务器自带的定位工具,下面这套流程,三分钟就能把谁在用这个端口问清楚。

新服务一启动就报错 Address already in use,或者反过来,服务明明跑着,浏览器却连不上——十次有九次是端口出了问题:要么被别的进程占了,要么服务根本没监听在你以为的那个端口上。ss 和 lsof 是每台 Linux 服务器自带的定位工具,下面这套流程,三分钟就能把"谁在用这个端口"问清楚。

1. 先看端口到底被谁占着:ss -tlnp

ss 是 netstat 的继任者,快得多,查监听端口只用一行:

ss -tlnp

四个参数各管一件事:-t 只看 TCP,-l 只看正在监听的,-n 不把端口反查成服务名(快,也不会被 DNS 拖慢),-p 显示占用进程的 PID 和名字。输出里找你要的端口,比如 8080 那行:

LISTEN 0  4096  0.0.0.0:8080  0.0.0.0:*  users:(("nginx",pid=1234,fd=6))

这一行信息量很大:0.0.0.0:8080 说明监听在所有网卡上,users 那段直接告诉你占着它的是 nginx、PID 1234。如果这一行根本没有,说明压根没人监听这个端口——问题不在"被占",在服务自己没起来,往服务日志方向查。

只查一个端口时加过滤更干净:

ss -tlnp | grep :8080

2. 反过来查:某个进程占了哪些端口

知道进程名、不知道它占了什么端口时,用进程名反查:

ss -tlnp | grep nginx

或者用 lsof 按进程查:

lsof -p 1234 | grep LISTEN

这招在"服务起了、端口却不是配置文件里写的那个"时特别管用——先确认它实际监听的端口,再去对配置。

3. lsof -i:按端口查进程的另一把刀

lsof -i :8080 是最直接的问法:

sudo lsof -i :8080

输出会给 COMMAND、PID、USER、监听地址一次列全。注意两点:一是 -p 参数要 root 或进程属主才看得全,普通用户查别人的进程会显示不全,查不到先加 sudo 再试;二是它也能查 UDP:lsof -i UDP:53,DNS 这类 UDP 服务被占时就靠它。

fuser 是更短的写法,适合只想拿 PID 的场景:

sudo fuser 8080/tcp

4. 占着端口的进程,该杀还是该留

定位到了,先别急着 kill。分三种情况:

  • 是自己服务的旧进程:部署脚本没杀干净、旧实例还在跑。先 kill <PID>,等它优雅退出;还不走再 kill -9。然后检查为什么旧进程没被收掉——systemd 的服务文件里 ExecStop 对不对、部署脚本有没有先停后起。
  • 是别的服务:比如 80 端口被 Apache 占着,你要起 Nginx。两个服务不能共用一个端口,要么改新服务的监听端口,要么把旧服务停掉(systemctl stop apache2),别直接 kill 系统服务。
  • 是 TIME_WAIT 的残留连接:ss -tan | grep TIME-WAIT 里一堆,但监听端口本身没被占——这不是"被占",服务重启报 Address already in use 时先看是不是监听 socket 没释放,SO_REUSEADDR 没开的老程序才会真卡在这一步。

杀之前多问一句:这个进程是谁起的、为什么在跑。ps -ef | grep 1234 看一眼启动命令和启动时间,生产服务器上杀错进程的代价,比端口冲突大得多。

5. 服务跑着却连不上:监听地址的坑

端口没被占、服务也在跑,浏览器还是连不上,先看监听地址那一列:

ss -tlnp | grep 8080
  • 127.0.0.1:8080:只监听了本机回环,外面连不进来是正常的。想对外提供服务,改配置绑 0.0.0.0,或者前面架一层 Nginx 反向代理(反向代理篇的做法)。
  • 0.0.0.0:8080:所有网卡都在听,连不上就往防火墙和安全组方向查——云服务器的安全组没放行这个端口,本地再通也没用。
  • [::]:8080:只监听了 IPv6。IPv4 的客户端连不上是正常的,改配置绑 0.0.0.0,或者确认你的客户端走的是 IPv6。

6. 三个真实踩坑

1. 改了配置没重启,查的还是旧端口。 服务读的是启动时加载的配置,改完配置文件必须重启(systemctl restart xxx)才生效。ss 看到的永远是"正在跑的那个进程"的实际监听,不是配置文件里写的。

2. 端口号小于 1024,普通用户起不来。 1024 以下的端口是特权端口,非 root 进程绑定会直接报权限错误。开发时用 8080,生产再用 systemd 或反向代理转到 80,别为了图省事全程 root 跑服务。

3. 容器里查不到,宿主机上查得到。 Docker 容器里的端口映射是宿主机上的 iptables 规则,容器内 ss 看不到宿主机的监听。服务起在容器里却连不上,先在宿主机上 ss -tlnp | grep <映射端口>,再进容器里查应用本身。

一句话总结

ss -tlnp 看谁在监听,lsof -i :端口 按端口找进程,ps 确认进程身份再动手。定位三分钟,动手前多想一秒——端口冲突好解决,杀错进程难收场。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。