You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring Boot后端运行数小时后出现异常,重启消失求排查思路

Hey,这种「运行数小时才出异常、重启就恢复」的问题我碰过好多次了,十有八九是资源泄漏或者状态累积搞的鬼!给你梳理几个核心排查方向,你可以按优先级一步步来:

核心排查思路

1. 先查资源泄漏(最常见原因)

  • 数据库连接池:重点检查HikariCP(Spring Boot默认)的配置,比如maximumPoolSizeidleTimeout是不是合理?有没有代码里手动获取连接后没关闭的情况?可以通过JMX监控连接池的活跃连接数变化,或者在日志里加debug级别的连接获取/释放日志,看是不是运行久了连接被彻底占满。
  • 线程泄漏:用jstack <pid>(Linux/Windows)或者VisualVM抓取线程快照,对比应用刚启动和异常发生后的线程数,看有没有大量阻塞、等待的线程堆积。比如如果自定义了ExecutorService,是不是没调用shutdown()导致线程一直存活?
  • 文件/IO句柄泄漏:有没有打开文件、Socket、NIO Channel后没在finally块里关闭的情况?Linux下可以用lsof -p <pid>查看进程的文件句柄数,Windows用资源监视器看句柄计数,如果数值持续增长不回落,基本就是泄漏了。

2. 内存相关问题排查

  • 内存泄漏(OOM前兆):用jmap -dump:format=b,file=heap.hprof <pid>生成堆快照,然后用VisualVM或者MAT分析,对比不同时间点的堆快照,看有没有对象(比如自定义缓存、未清理的用户会话)持续增长不被GC回收。比如如果用了HashMap做本地缓存,是不是没设置过期逻辑导致数据越存越多?
  • GC异常:给应用加GC日志启动参数:-Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCTimeStamps,查看异常发生前后的GC情况,是不是FullGC频繁触发,或者GC耗时太长导致业务请求超时?有时候内存碎片过多也会导致大对象分配失败触发异常。

3. 外部依赖与状态异常

  • 第三方服务连接问题:如果你的应用调用了外部API、MQ或者其他服务,检查是不是连接池配置不合理,或者重试机制太激进导致连接堆积?比如HTTP客户端没设置最大连接数,运行久了连接耗尽;或者MQ消费者卡住,导致消息堆积占用大量内存/线程。
  • 缓存一致性问题:如果用了Redis、Guava Cache这类缓存,检查是不是缓存过期逻辑失效,或者缓存与数据库数据不一致,运行久了脏数据累积触发业务异常?比如缓存更新时机错误,导致老数据一直存在。
  • 定时任务隐患:有没有定时任务运行时间过长、重复执行的情况?比如定时任务没加分布式锁,多实例重复执行导致资源耗尽;或者任务内部有内存泄漏,每次执行都占一点资源,积少成多。

4. 日志与监控辅助排查

  • 增加关键场景日志:在异常发生的代码块、资源获取/释放的地方加详细日志,比如打印时间戳、线程ID、连接池剩余连接数、缓存大小这些关键状态,等异常再次出现时,就能通过日志定位到具体的触发操作。
  • 实时监控核心指标:用Spring Boot Actuator配合Prometheus+Grafana,监控应用的CPU、内存、连接池活跃数、线程数、GC次数这些指标,看异常发生时哪个指标出现突变,缩小排查范围。
  • 尝试复现问题:如果测试环境能模拟,用JMeter这类压测工具模拟高负载运行,加速问题出现,这样排查效率会高很多。比如持续压测几个小时,看是不是和生产环境一样触发异常。

5. 代码逻辑的隐性隐患

  • 并发安全问题:有没有线程不安全的代码?比如多线程下用了ArrayListHashMap这类非线程安全集合,或者共享变量没加锁,运行久了数据错乱触发异常?
  • 业务状态累积:业务逻辑里有没有状态流转异常的情况?比如某个流程的状态没正确更新,导致错误状态的请求堆积,运行久了触发异常。

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

火山引擎 最新活动