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

Spring Boot基于Rest Api的服务长时间运行偶发无响应问题求助

Java Rest服务长时间运行偶发无响应问题排查方案

可能触发原因

  • JVM线程池耗尽:内置web容器(Tomcat/Undertow/Jetty)的工作线程被慢请求、死锁、阻塞操作全部占满,新请求进入等待队列后无法被处理,此时端口仍处于监听状态但无业务逻辑执行,因此没有新日志生成
  • JVM GC异常停顿:堆内存泄漏导致老年代占满,持续触发Full GC,元空间/直接内存溢出,都会导致JVM长时间停顿,无法响应任何业务请求
  • 系统资源耗尽:Java进程打开的文件句柄数超过系统ulimit限制,无法为新的请求分配文件描述符;系统内存占满后swap分区被大量使用,进程响应速度骤降
  • 框架配置不合理:web容器的最大连接数、最大工作线程数、等待队列长度配置过低,并发请求量超过阈值后新请求直接被丢弃或阻塞
  • 全局锁死锁:拦截器、过滤器、公共工具类中的全局同步锁出现死锁,所有请求执行到对应逻辑时全部阻塞

可落地排查步骤

问题发生时先不要重启服务,第一时间采集以下信息定位根因:

JVM层面排查

  1. 执行jps获取Java服务的进程PID
  2. 执行jstack [PID] > jstack_$(date +%Y%m%d%H%M).log导出线程栈,分析是否存在死锁,是否有大量HTTP工作线程处于BLOCKED/WAITING状态
  3. 执行jstat -gcutil [PID] 1000 10查看GC状态,确认是否存在Full GC频繁、GC耗时占比过高的情况
  4. 执行jmap -dump:format=b,file=dump_$(date +%Y%m%d%H%M).hprof [PID]导出堆转储文件,事后分析是否存在内存泄漏

操作系统层面排查

  1. 执行lsof -p [PID] | wc -l统计进程打开的文件句柄数,和ulimit -n的返回值对比,确认是否触及句柄上限
  2. 执行top -p [PID]查看进程CPU、内存占用率,执行free -h确认系统内存、swap分区占用情况
  3. 执行netstat -anp | grep [服务端口]统计TCP连接状态,确认是否存在连接数溢出的情况

应用层面排查

  1. 检查web容器配置,确认最大工作线程数、最大连接数、等待队列长度是否符合业务并发需求,例如SpringBoot内置Tomcat的默认最大线程数仅为200,高并发场景下很容易耗尽
  2. 排查全局拦截器、过滤器、公共依赖中是否存在未释放的锁、未设置超时时间的同步IO操作

通用解决方案

  • 给JVM添加GC日志、堆转储自动生成参数:-Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./,方便后续问题回溯
  • 调整系统ulimit参数,将进程最大打开文件句柄数调整为65535或更高,永久生效可修改/etc/security/limits.conf配置
  • 根据服务器配置和业务并发量,调大web容器的最大连接数、工作线程数、等待队列长度参数
  • 优化慢请求逻辑,所有外部依赖调用(第三方接口、缓存、消息队列)必须设置合理的超时时间,避免阻塞工作线程

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 09:24:02