You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot嵌入式Tomcat服务部署时停止响应请求求助

问题分析与解决方案

首先,咱们来拆解下你遇到的问题:服务明明还在监听端口,但完全不响应请求,核心原因大概率和你在服务运行时移动target目录的操作有关,具体分析和解决办法如下:

根因分析

Linux系统中,虽然进程打开的文件句柄不会因为目录移动而直接失效(因为文件的inode没变化),但你的Spring Boot应用可能存在以下依赖场景:

  • 应用运行时需要读取target目录下的其他文件(比如外部配置、静态资源、自定义的业务文件等),当target被移走后,这些文件的路径直接失效,导致请求处理线程卡在文件读取操作上,最终整个Tomcat线程池被占满,无法处理新请求。
  • 嵌入式Tomcat会对部分资源路径做缓存,当target目录结构被修改(移走再重建)后,缓存的路径失效,引发资源加载异常,阻塞请求流程。

解决方案

1. 修正部署流程(最直接的解决方式)

永远不要在服务运行时移动存放当前运行Jar包的目录,正确的部署步骤应该是:

  • 停止当前服务:
    先找到进程ID:
    ps aux | grep abc.jar | grep -v grep
    
    然后优雅停止(如果配置了actuator的shutdown端点,也可以用curl -X POST localhost:8090/shutdown):
    kill <进程ID>
    
  • 备份旧Jar包:
    不要移动整个target目录,而是单独备份Jar文件:
    mkdir -p old_target
    cp target/abc.jar old_target/abc.jar.$(date +%Y%m%d%H%M%S)
    
  • 部署新Jar包:
    将新Jar包复制到target目录后,重新启动服务:
    java -jar -Dspring.profiles.active=local -Dserver.port=8090 target/abc.jar > /dev/null 2>&1 &
    

2. 临时恢复当前无响应的服务

如果你想快速验证目录移动是否是根因,可以尝试把old_target移回原来的位置:

mv old_target target

如果服务恢复响应,就可以确认是目录移动导致的问题。

3. 生产环境的零停机部署方案(进阶)

如果需要避免服务中断,推荐以下方式:

  • 使用容器化部署:比如用Docker打包你的Spring Boot应用,通过Docker的滚动更新功能实现零停机部署。
  • 采用蓝绿部署策略:先启动新版本的服务(使用不同端口或域名),验证正常后切换流量到新版本,再停止旧版本服务。
  • 借助Spring生态工具:比如Spring Cloud Gateway作为网关,配合服务注册中心(Eureka)实现平滑的服务切换。

4. 排查具体阻塞原因(定位问题细节)

如果想进一步确认是哪个环节出了问题,可以做以下操作:

  • 查看应用日志:如果你的应用配置了文件日志(不是只重定向到/dev/null),去日志目录查看是否有文件读取失败、线程阻塞相关的报错。
  • 导出线程栈:用jstack命令查看线程状态:
    jstack <进程ID> > thread_dump.txt
    
    打开thread_dump.txt,查找处于BLOCKED或WAITING状态的线程,看是否和文件操作相关。
  • 查看文件句柄:用lsof命令确认进程打开的文件:
    lsof <进程ID> | grep abc.jar
    
    可以看到原来的Jar文件是否还被进程正常持有。

内容的提问来源于stack exchange,提问作者Shubham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:12:28