如何利用 Spring Boot Actuator 的 threaddump 端点高效排查 Web 界面系统挂起问题?
- 内容介绍
- 相关推荐
本文共计704个文字,预计阅读时间需要3分钟。
直接结论:
为什么浏览器打开 /actuator/threaddump 看起来像“挂了”
浏览器直接访问 /actuator/threaddump 时,会收到一个超大 JSON 响应(可能数 MB),没有前端渲染逻辑,导致页面长时间白屏、卡顿甚至崩溃。这不是服务挂起,而是浏览器在尝试解析并展示海量线程数据——它根本不是设计给人肉阅读的。
- Spring Boot 2.x+ 默认不暴露
threaddump端点,必须显式配置management.endpoints.web.exposure.include=threaddump,health,info - 响应体是扁平化 JSON 数组,每个线程含
threadName、threadState、stackTrace字段,无折叠、无搜索、无高亮 - Chrome/Firefox 对 >5MB 的 JSON 渲染极慢,Safari 可能直接拒绝解析
真正有效的 threaddump 分析三步法
别指望浏览器当分析器。你需要的是可操作、可比对、可存档的诊断流:
- 用
curl -s http://localhost:8080/actuator/threaddump | jq '.' > threaddump-$(date +%s).json保存原始快照(需安装jq) - 重点关注
threadState为WAITING、BLOCKED或长时间RUNNABLE的线程(比如堆栈里反复出现Object.wait、LockSupport.park、SocketInputStream.read) - 对比两次 dump:用
diff threaddump-1713879xxx.json threaddump-1713879yyy.json找出“不动的线程”,它们大概率就是阻塞源头
常见误配导致 threaddump 根本调不通
即使加了依赖,threaddump 也常因配置疏漏返回 404 或 401:
-
management.endpoint.threaddump.show-locks=true是可选的,但若没加这行,dump 中不会包含锁持有者信息(如lockedMonitors、lockedSynchronizers),排查死锁几乎不可能 - 若启用了 Spring Security,默认所有 actuator 端点都会被拦截;必须显式放行:
http.authorizeHttpRequests(authz -> authz.requestMatchers("/actuator/threaddump").permitAll())(注意路径带/actuator/前缀) - Spring Boot 3.x 起,
spring-boot-starter-actuator不再自动拉取 JMX 相关类;如果应用跑在容器里且禁用了 JMX,则threaddump可能降级为仅返回有限线程信息(尤其是非 JVM 线程如 Netty EventLoop 可能缺失)
真正卡住的系统,往往不是线程全停,而是少数几个关键线程死锁或无限等待——而 threaddump 就是唯一能让你在不重启、不改代码的前提下,一眼锁定它们的工具。别把它当网页用,要当证据链用。
本文共计704个文字,预计阅读时间需要3分钟。
直接结论:
为什么浏览器打开 /actuator/threaddump 看起来像“挂了”
浏览器直接访问 /actuator/threaddump 时,会收到一个超大 JSON 响应(可能数 MB),没有前端渲染逻辑,导致页面长时间白屏、卡顿甚至崩溃。这不是服务挂起,而是浏览器在尝试解析并展示海量线程数据——它根本不是设计给人肉阅读的。
- Spring Boot 2.x+ 默认不暴露
threaddump端点,必须显式配置management.endpoints.web.exposure.include=threaddump,health,info - 响应体是扁平化 JSON 数组,每个线程含
threadName、threadState、stackTrace字段,无折叠、无搜索、无高亮 - Chrome/Firefox 对 >5MB 的 JSON 渲染极慢,Safari 可能直接拒绝解析
真正有效的 threaddump 分析三步法
别指望浏览器当分析器。你需要的是可操作、可比对、可存档的诊断流:
- 用
curl -s http://localhost:8080/actuator/threaddump | jq '.' > threaddump-$(date +%s).json保存原始快照(需安装jq) - 重点关注
threadState为WAITING、BLOCKED或长时间RUNNABLE的线程(比如堆栈里反复出现Object.wait、LockSupport.park、SocketInputStream.read) - 对比两次 dump:用
diff threaddump-1713879xxx.json threaddump-1713879yyy.json找出“不动的线程”,它们大概率就是阻塞源头
常见误配导致 threaddump 根本调不通
即使加了依赖,threaddump 也常因配置疏漏返回 404 或 401:
-
management.endpoint.threaddump.show-locks=true是可选的,但若没加这行,dump 中不会包含锁持有者信息(如lockedMonitors、lockedSynchronizers),排查死锁几乎不可能 - 若启用了 Spring Security,默认所有 actuator 端点都会被拦截;必须显式放行:
http.authorizeHttpRequests(authz -> authz.requestMatchers("/actuator/threaddump").permitAll())(注意路径带/actuator/前缀) - Spring Boot 3.x 起,
spring-boot-starter-actuator不再自动拉取 JMX 相关类;如果应用跑在容器里且禁用了 JMX,则threaddump可能降级为仅返回有限线程信息(尤其是非 JVM 线程如 Netty EventLoop 可能缺失)
真正卡住的系统,往往不是线程全停,而是少数几个关键线程死锁或无限等待——而 threaddump 就是唯一能让你在不重启、不改代码的前提下,一眼锁定它们的工具。别把它当网页用,要当证据链用。

