售前咨询400-838-0503

Linux端口被占用怎么办?

发布:2026-11-03 12:38

搜索全部帮助分类的文档

启动程序时,如果出现以下报错:

Address already in use

或者Docker提示:

port is already allocated

通常说明程序尝试使用的地址和端口发生了冲突。

处理前应先查清楚是谁占用了端口,以及这个服务是否仍在使用。下面以8080端口为例,实际操作时请替换为报错中的端口。

一、查询端口占用情况

检查TCP监听端口:

sudo ss -ltnp 'sport = :8080'

如果报错涉及UDP,则执行:

sudo ss -lunp 'sport = :8080'

参数含义如下:

参数 作用
-l 查看监听或等待接收的套接字
-t 查看TCP
-u 查看UDP
-n 使用数字显示地址和端口
-p 显示关联进程信息

可能看到类似结果:

LISTEN 0 511 127.0.0.1:8080 0.0.0.0:*
    users:(("node",pid=2468,fd=7))

这个示例表示:PID为2468的Node.js进程正在监听TCP 8080端口。

需要同时关注监听地址:

  • 127.0.0.1:8080:监听IPv4回环地址。

  • 0.0.0.0:8080:监听所有本地IPv4地址。

  • [::]:8080:监听IPv6通配地址;是否同时接收IPv4连接,取决于套接字设置。

TCP和UDP需要分别检查。 UDP 8080被占用,并不等于TCP 8080也被占用。

Linux使用ss查询TCP和UDP端口占用进程

二、确认进程属于哪个程序或服务

查到PID后,查看程序路径、启动参数和运行用户:

ps -p 2468 -o pid,ppid,user,args

2468是示例PID,需要替换成查询到的实际值。

如果服务器使用systemd管理服务,还可以执行:

sudo systemctl status 2468 --no-pager

该命令可以帮助查看进程所属的systemd单元。例如:

demo-api.service - Demo API
Active: active (running)
Main PID: 2468 (node)

接下来应确认:

  1. 这是不是已经正常运行的业务。

  2. 是否重复执行了启动命令。

  3. 是否有面板、systemd、Supervisor或PM2负责管理它。

  4. 新启动的程序是否本来就应该使用另一个端口。

返回的单元也可能是登录会话等其他类型,不能看到单元名称就直接停止,需要结合程序路径和业务用途判断。

使用ps和systemctl确认端口占用进程所属服务

三、Docker部署还要检查端口映射

如果服务器运行了Docker,查看容器及其端口映射:

docker ps --format 'table {{.Names}}\t{{.Ports}}'

例如下面这种映射:

127.0.0.1:8080->80/tcp

表示宿主机的TCP 8080端口映射到了容器内的80端口。

排查时要区分:

位置 示例 含义
宿主机端口 8080 外部客户端或反向代理访问的端口
容器端口 80 应用在容器内部监听的端口

两个使用独立网络命名空间的容器,可以各自在内部监听80端口;但发布到宿主机时,不能随意使用相同且冲突的宿主机地址和端口。

Docker端口发布可能通过转发规则实现,因此不能仅凭ss中没有看到docker-proxy,就认定没有容器占用该端口。还应核对容器端口映射。

如果容器使用network_mode: host,则直接共享宿主机网络,需要按宿主机端口冲突处理。

四、选择停止重复实例或修改端口

确认占用来源后,根据业务情况选择处理方式。

情况一:原来的服务仍然需要运行

保留原服务,为新应用选择其他未冲突的端口,例如8081。

随后同步调整访问地址、反向代理、健康检查及其他调用方配置。

情况二:确实是可以停止的旧服务

如果已经确认demo-api.service是可以停止的旧实例,可以执行:

sudo systemctl stop demo-api.service

服务名必须替换为实际名称。停止后,再次查询8080端口,确认是否释放。

如果程序由Docker、面板、Supervisor或PM2管理,应通过对应管理工具停止,避免直接结束子进程后又被自动启动。

某些服务由systemd套接字激活,可以先检查:

sudo systemctl list-sockets --all --no-pager

存在相关.socket单元时,仅停止业务进程或.service,可能无法释放监听端口,需要核对对应套接字单元。

不要在未确认用途的情况下,直接批量强制结束占用端口的进程。

五、示例:修改Docker Compose宿主机端口

假设已有一个Compose服务叫web,容器内部监听80端口,准备将宿主机端口从8080改为8081。

先按第1节检查8081,并核对现有Docker映射,然后修改现有配置中的ports:

services:
  web:
    # 保留现有 image、volumes、environment 等配置
    ports:
      - "127.0.0.1:8081:80"

这是配置节选,不能直接覆盖完整的Compose文件。

本例绑定宿主机回环地址,适合由宿主机上的反向代理访问。需要公网直连时,应按实际部署要求选择绑定地址并配置访问控制。

修改完成后,在该Compose项目目录中执行:

docker compose config -q && docker compose up -d web

web是示例服务名,需要替换成实际名称。使用多个配置文件或自定义项目名的部署,应沿用原来的启动参数。

端口映射变化会涉及容器重建。执行前确认业务数据已通过数据卷或绑定目录持久化,并安排好可能出现的短暂中断。

只执行docker compose restart不会应用修改后的端口映射。

查看最终映射:

docker compose port web 80

本例预期输出:

127.0.0.1:8081

容器内应用仍监听80端口,宿主机访问端口已经改为8081。

Docker Compose修改宿主机端口并验证映射结果

六、验证服务启动及访问结果

对于普通宿主机服务,可以再次检查监听情况:

sudo ss -ltnp 'sport = :8081'

核对监听地址、端口和进程是否符合预期。

对于Docker服务,应结合容器状态、端口映射和应用日志确认结果。

如果是HTTP应用,可以在宿主机上测试:

curl -i --max-time 10 http://127.0.0.1:8081/

路径和协议应按实际应用调整。HTTPS服务或其他协议,应使用相应的地址和客户端测试。

最后确认:

  1. 服务不再出现端口绑定失败。

  2. 实际页面或业务接口能够正常使用。

  3. 反向代理和监控已使用正确端口。

  4. 由原来的服务管理方式启动时,不会再次产生重复实例。

端口成功监听,只能说明绑定成功,还需要验证业务结果。

常见问题

1. 为什么结束进程后,端口马上又被占用了?

程序可能受到systemd、Docker重启策略、Supervisor或PM2管理。应先确认管理来源,再通过对应工具停止或修改配置。

2. ss没有查到监听,为什么仍然报端口被占用?

需要核对TCP或UDP、IPv4或IPv6,以及命令执行的位置是否与应用处于同一网络命名空间。Docker部署还应检查宿主机端口映射。

也可能是程序启动过程中重复绑定同一地址和端口,需要查看完整启动日志。

3. 放行防火墙端口,能解决端口被占用吗?

不能。端口占用属于本地地址绑定冲突,防火墙放行主要影响流量是否能够通过,两者是不同问题。

注意事项

修改前备份相关配置,先确认占用进程的业务用途。不要通过重启整台服务器代替定位,也不要直接停止数据库、SSH或正在提供服务的程序。

如果使用莱卡云服务器后仍无法定位问题,可提交工单,提供完整报错、端口号、TCP或UDP协议、进程查询结果及部署方式,便于进一步排查。分享启动参数和日志前,请隐藏密码、令牌等敏感信息。

按文档操作后还是不行,把机器编号、出问题的时间点和现象截图一起提工单,能少来回一轮。

提交工单