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

Spring Boot API处理错误后CPU无法恢复至空闲状态

针对Spring Boot API异常请求后CPU无法恢复的解决方案建议

问题概述

我们的Spring Boot API每月会出现一次性能下降,仅能通过重启应用恢复。经排查,向抛出异常的特定控制器发送大量HTTP请求后,CPU使用率无法回落至正常水平。复现步骤:

  • 运行多实例含无限循环的bash脚本,发送触发异常的HTTP请求
  • 等待服务器CPU使用率达100%
  • 等待15分钟
  • 停止bash脚本的无限循环

停止请求后,通过Java VisualVM观察到CPU仍维持在25%左右,堆直方图显示io.micrometer.core.instrument.Tag[]实例数最多。已尝试升级Spring Boot版本、设置系统变量LatencyUtils.useActualTime=false、手动执行垃圾回收等操作,均未解决问题。期望无请求时CPU/内存能恢复至空闲水平。


解决方案建议

1. 排查Micrometer Tag相关的内存泄漏与CPU负载

  • 检查异常处理流程中的Tag创建逻辑:若异常监控逻辑每次触发都新建Tag[]实例而非复用,高并发下会产生大量对象,若存在未释放的引用,会导致内存堆积,进而引发后台统计线程持续占用CPU。可临时复用固定Tag实例进行测试,验证CPU是否回落
  • 验证异常相关指标配置:若针对该控制器的异常请求设置了高频更新的指标,即使请求停止,Micrometer的后台统计线程可能仍在处理残留数据。可临时禁用该接口的异常监控指标,复现测试观察CPU变化
  • 检查Tag值的合理性:避免动态生成唯一值、超长字符串作为Tag值,这类值会导致Tag无法被缓存复用,大量实例堆积触发频繁GC或后台线程负载过高

2. 分析异常处理的线程与资源释放逻辑

  • 导出线程栈快照(使用jstack命令):排查是否有大量线程卡在异常处理逻辑中,比如自定义线程池的任务堆积、@ControllerAdvice中存在循环调用或未释放的资源(如数据库连接、文件句柄)
  • 检查异步异常处理逻辑:若异常处理中使用了异步任务,高并发下可能造成任务队列堆积,即使请求停止,线程池仍在处理残留任务,导致CPU持续占用

3. 定位Tag[]实例的引用链

  • 使用jmap -histo或Java VisualVM的内存分析功能,查看io.micrometer.core.instrument.Tag[]实例的引用持有者,确认是Micrometer的指标注册表、自定义监控逻辑还是其他组件未释放引用,精准定位泄漏点

4. 优化Micrometer配置与版本

  • 启用Tag缓存:部分Micrometer版本支持Tag实例复用,可配置management.metrics.tags.cache.enabled=true(需对应Spring Boot版本支持),减少对象创建
  • 调整指标采样频率:降低异常相关指标的采样频率,减少后台统计线程的负载
  • 单独升级Micrometer:即使升级了Spring Boot,可能内嵌的Micrometer仍存在已知问题,可单独将Micrometer核心依赖升级至最新稳定版,排查是否修复了相关内存泄漏/CPU占用问题

5. 流量控制与异常逻辑优化

  • 给触发异常的接口添加流量限制:在网关层或控制器中设置QPS阈值,避免短时间内大量请求耗尽系统资源
  • 简化异常返回逻辑:异常处理时避免执行复杂的统计、IO操作,减少资源消耗,确保线程能快速释放

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 10:15:08