DevFix
Spring Boot已验证

Spring Boot 启动报 Port 8080 was already in use?端口占用的排查与释放

@debug_master更新于 3 天前阅读 6 min0

一句话先说结论:Spring Boot 内嵌的 Web 服务器默认监听 8080,一旦已有进程占着这个端口,JVM 抛 BindException,应用直接启动失败。解决无非两条:找到并结束占用进程,或者换个端口。这是最基础的坑,但每次都有人栽在“IDE 没停干净”上。

背景

Spring Boot 用内嵌容器(默认 Tomcat)让应用“打成 jar 直接跑”,不需要额外部署到独立 Tomcat。带来的一个副作用是:内嵌容器默认绑定 8080 端口。这个端口同时也是 Tomcat 独立版、Jenkins、Nexus、以及各种开发工具默认爱用的端口,冲突概率极高。

现象

启动时立即失败,控制台报:

***************************
APPLICATION FAILED TO START
***************************

Description:

Web server failed to start. Port 8080 was already in use.

Action:

Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.

底层异常是 Tomcat 的 BindException

org.apache.catalina.LifecycleException: Protocol handler start failed
Caused by: java.net.BindException: Address already in use: bind

同一时刻一个端口只能有一个进程监听,第二个人再来绑就会失败。

根因分析

消息本身已经说得很明白:8080 被占了。值得记的是它为什么被占——常见四种:

  1. 上一个实例没停干净:在 IDE 里又重新点了一次 Run,前一个 java 进程还活着,或者 java -jar 在后台跑着。
  2. IDE 留下了僵尸进程:IntelliJ/Eclipse 在崩溃或强停后,有时不会真正结束 Java 进程。
  3. 别的服务默认也用 8080:独立 Tomcat、Jenkins、Nexus、WildFly 等。
  4. Docker 容器映射了 8080:容器里跑的可能完全是别的服务,但宿主机这一侧的端口绑定照样挡住你的 Spring Boot 应用。

解决方案

方案 A:找到并结束占用进程

一条命令先查出是谁占了端口。

macOS / Linux:

lsof -i :8080

输出里 PID 那列就是进程号,例如:

COMMAND   PID  USER   FD  TYPE DEVICE SIZE/OFF NODE NAME
java    18902  marco  48u IPv6 ...  0t0  TCP *:8080 (LISTEN)

先尝试优雅退出,不行再强杀(-9 是最后手段,不留给进程做清理的机会):

kill 18902
# 若还活着
kill -9 18902

一条命令直接查 PID 并杀掉:

kill -9 $(lsof -ti :8080)

Windows:

netstat -ano | findstr :8080
:: 最后那列就是 PID
taskkill /PID 1234 /F

如果是 Docker 占的端口,先定位容器:

docker ps --filter publish=8080

方案 B:换个端口

不想动别人的进程,就让自己的应用换端口。

application.properties

server.port=8081

application.yml

server:
  port: 8081

命令行临时指定:

java -jar your-app.jar --server.port=8081

环境变量(借助 Spring Boot 的 relaxed binding,SERVER_PORT 会自动映射到 server.port):

export SERVER_PORT=8081
java -jar your-app.jar

方案 C:测试时用随机端口

集成测试或本地起多个实例时,把端口设成 0,让容器选一个空闲端口:

server.port=0

运行时通过 @Value("${local.server.port}") 拿到实际端口。

小结

  • 端口占用是“资源冲突”,不是代码问题,先查 lsof/netstat 再决定杀还是换。
  • kill -9 是最后手段,能优雅退出就别强杀。
  • 记住配置优先级:命令行参数 > 环境变量 > 配置文件 > 默认 8080,端口改了没生效多半是更高优先级的来源覆盖了它。
  • 预防:IDE 里用 Stop 停干净再 Run;不同服务约定不同端口;顺手 docker ps 看看有没有容器占着。

来源

最后更新于 2026-08-22

这篇帮到你了吗?

刚解决了一个棘手的报错?花两分钟记录下来,帮助下一个遇到同样问题的开发者。

贡献一条解法