Arthas实战手册:Java线上诊断、性能分析与故障排查

发布时间:2026/10/19 8:50:45

Arthas实战手册:Java线上诊断、性能分析与故障排查 1. Arthas 是什么为什么线上出了事大家第一个想到它多年前我第一次遇到线上 Java 服务 CPU 飙到 99% 却没有监控权限运行日志里只有几行无关痛痒的 WARN当时那种“既不能重启、又不能断点调试、代码也不敢乱动”的无助感相信每个搞 Java 的人都体会过。后来我在一次紧急排查中第一次用到了 Arthas差不多五分钟就定位到是哪条线程在空转、哪个方法进入了死循环那一刻我就确定这类 Java 线上诊断工具应该成为后端同学的基础装备。Arthas 是阿里巴巴开源的一款 Java 诊断工具江湖上常把它叫“Java 界的瑞士军刀”。它最大的特点是不需要重启目标进程不需要改代码也不需要提前埋点就能直接附着到一个正在运行的 JVM 上实时查看内存、线程、类加载、方法调用链甚至可以做反编译和热替换。说白了它让你在产线运维现场拥有近似本地的调试体验而不是靠猜日志和反复发布来碰运气。这篇文章适合三类人一是负责线上故障应急的后端开发二是经常处理服务异常的运维工程师三是准备做性能压测和调优的测试开发。不管你之前听过多少命令我希望通过这篇文章把 Arthas 的定位、常用命令、排查思路和踩坑经验一次性讲清楚并且拆成可以直接抄作业的组合拳。1.1 传统 Java 线上排查绕不开的三座大山很多人在本地用 IDE 调试时觉得 Java 排查问题很舒服可一到线上就束手束脚本质上是被三个现实条件卡住了。首先是“不能重启”。线上服务往往承载着用户请求、分布式任务、本地缓存一旦重启就可能导致请求失败、缓存失效、任务状态丢失。所以很多使用方明确要求优先在线诊断禁止轻易重启服务。这种情况下你不可能通过重启加日志再复现问题。其次是“不能断点调试”。生产环境根本没有你 IDE 的调试通道即使有也不可能因为你一个人想看某个变量就暂停请求那等于在线业务停机。而且代码往往经过构建工具压缩、混淆本地代码和线上代码未必完全一致。第三是“没有观测数据”。很多时候 CPU 飙高、接口变慢、内存异常这些问题发生的时间窗口很短你事后看监控只能看到一个尖峰根本不知道尖峰期间进程内部发生了什么。比如 GC 频繁、死锁、线程池耗尽、锁竞争、正则灾难性回溯这些都需要进入进程内部才能看到。Arthas 的价值就是破掉这三座大山它不进业务代码不重启业务进程通过 JVM 自带的能力“贴”到进程上拿到运行时的真实现场。1.2 Arthas 不重启就“动手术”的原理Arthas 能做到这一切核心依赖三件事JVM 的 Attach 机制、Java Agent 和字节码增强。JVM 提供了 Attach API它允许外部进程“附着”到一个已经在运行的 JVM 上。Arthas 启动后会去枚举当前主机上的 Java 进程当你选择目标 PID 后它会通过 Attach API 把自身打包好的 Agent 注入目标 JVM。这个 Agent 被加载后会在目标 JVM 内启动一个控制台服务所以你后续看到的交互式提示符其实是跑在目标 JVM 进程内部的而不是外部壳。字节码增强则是 Arthas 大部分命令的底层操作方式。比如 watch 一个方法Arthas 会把字节码编织到目标方法的入口、出口或异常路径上在运行时插入一段观测逻辑。这个过程不需要源码参与却能达到类似 aop 的效果。正因为有这套机制Arthas 才可以做到反编译运行中的类查看某个方法每次调用的入参甚至修改方法体后重新加载。它等于在运行中的 JVM 里装了一台显微镜和一双手。提示Arthas 挂载之后会产生一点额外开销虽然正常很低但仍建议“用完即走”。后面会详细说。2. 环境准备与首次启动把 Arthas 挂到目标 JVM使用 Arthas 之前你只需要准备一个本机命令行环境以及一个想诊断的 Java 进程。整个过程不需要改业务代码不需要在 pom 或构建配置里加任何依赖。2.1 下载与启动 Arthas先确认当前机器上有 JDK 环境不一定和业务进程是同一个 JDK但要能正常执行 java 命令。然后在命令行里下载 arthas-boot.jarcurl -O https://arthas.aliyun.com/arthas-boot.jar下载完成后直接执行java -jar arthas-boot.jar启动脚本会做几件事自动检测本机 Java 进程列表、检查本地是否已有 Arthas 发布包、必要时自动下载依赖最后展示一个进程选择菜单。如果下载依赖比较慢可以在启动时指定国内镜像源java -jar arthas-boot.jar --repo-mirror aliyun这时候你会看到一个进程列表每一行都有编号、PID 和进程名称。输入目标进程前面的序号并回车Arthas 就会附着上去。如果想要非交互式地直接指定进程也可以java -jar arthas-boot.jar --select 12345其中 12345 换成目标 Java 进程的 PID。2.2 进入控制台后能看到什么附着成功后终端会进入 Arthas 自己的交互控制台提示符长这样[arthas12345]$在这个控制台里你可以敲各种诊断命令。Arthas 还支持 Tab 键补全所以即使记不住完整命令也能靠 tab 快速提示。要注意的是Arthas 和操作系统终端并不完全相同。它默认会开放一个本地端口用于交互也可以配置成只监听本机回环地址避免被外部网络访问。多人在同一台机器上使用时最好指定不冲突的端口。2.3 退出和卸载的区别很多新手在这个环节会踩坑在交互控制台里输入 exit并不是让 Arthas 从目标 JVM 卸载仅仅是把当前客户端控制台关掉Arthas Agent 还留在目标 JVM 里资源也还占用着。真正把 Agent 从目标 JVM 里卸载需要执行stop执行 stop 后Arthas 才会释放对目标 JVM 的控制能力。所以在生产环境上用完一定要记得 stop。如果你是远程排查中途断了 SSH 连接arthas 会话可能会继续挂着最好通过后台方式检查一次进程占用。3. 高频命令实操Arthas 中最常用的 8 类命令Arthas 官方命令很多但日常排查其实主要就是围绕看整体、查线程、看代码、观察入参、追链路、看内存、做热修这七个场景。我把所有常用能力合并成以下几条主线来讲每条都附上典型用法和我的使用习惯。3.1 dashboard一眼看清 JVM 全局状态进入 Arthas 后如果没有任何线索我会先敲 dashboarddashboard它的作用类似 Linux 的 top但输出的是 Java 进程内部的运行概况。默认会展示线程概况、内存分区占用、GC 统计和 JVM 系统属性等信息。在 CPU 突然飙高的时刻dashboard 能直接告诉我们到底哪个线程在大量消耗 CPU哪块内存区域涨得异常。dashboard 默认是实时刷新的如果不想一直刷屏可以用参数控制刷新间隔和次数dashboard -i 5000 -n 10这个命令表示每 5 秒刷新一次最多刷新 10 次适合采集一段时间内的趋势。我会先跑一次短观察记录线程 ID 和内存数据然后切到 thread 命令做进一步确认。3.2 thread线程级排查看这里如果说 dashboard 是总览thread 就是放大镜。定位线程问题最常用的几个变体thread -n 3-n 3 表示找出 CPU 占用最高的前 3 个线程。在 CPU 飙升场景下这个命令几乎百发百中。看到线程后可以继续查看它的完整堆栈thread 42这里 42 是 dashboard 或 thread 列出来的线程 ID。堆栈会直接告诉你这段代码卡在哪个类的哪一行。thread 还能查阻塞情况thread -b这个命令会显示当前阻塞其他线程的锁和线程栈处理死锁问题时特别管用。当年我排查一个支付回调任务一直卡住的问题就是靠 thread -b 发现两个线程互相持有对方的锁。3.3 jad反编译线上正在跑的代码线上代码和本地代码经常“差了一点”最稳妥的办法是不要猜直接看 JVM 里实际加载的字节码反编译出来的源码。命令很简单jad com.example.demo.HelloController这里要填的是类的全限定名。反编译完成后Arthas 会显示源码路径、类加载器信息和 Java 源代码。如果只想拿源码文本在命令里加jad --source-only com.example.demo.HelloController适合把反编译结果导到本地文件里比对。我用 jad 最多的场景有三个确认线上代码到底有没有包含最新修复看某个配置类的静态值是什么以及为后续 redefine 热修提前准备源码。注意jad 能看到什么取决于 Arthas 能否找到这个类。如果类名没写全或者类由自定义类加载器加载可能查不到此时先用 sc 配合类加载器 hash 定位。3.4 watch观察方法的入参、返回值和异常定位到某个可疑方法后我通常会想看看这个方法的入参到底长什么样。watch 命令就是干这个的watch com.example.demo.OrderService createOrder params[0]拆开解释一下第一个参数是类名第二个是方法名第三个是 OGNL 表达式表示要观察什么。这里 params[0] 表示第一个入参对象。默认情况下每次调用这个方法都会打印入参以及返回结果。如果只想关注满足某些条件的情况可以加第四个参数作为过滤条件。比如只看大额订单watch com.example.demo.OrderService createOrder params[0] params[0].amount 1000还可以用 -e 参数把方法抛出的异常也抓出来watch com.example.demo.OrderService createOrder {params, throwExp} -e把参数和异常对象放在一个集合里输出适合定位“某个请求莫名其妙抛异常”的场景。watch 命令威力大但别过度使用。它在线上会拦截每个符合条件的调用高吞吐接口如果加了太重或太宽泛的表达式可能造成额外开销。我的习惯是条件尽量收紧观察次数尽量短。3.5 trace把慢接口的耗时层层拆开线上接口变慢最烦人的是不知道慢在哪一环。凭借经验盲猜数据库或者外部调用往往猜错。trace 命令可以把一次调用的内部耗时按照调用关系展开trace com.example.demo.PayController submit #cost 200这个命令表示追踪 PayController 里的 submit 方法只输出耗时超过 200ms 的调用。执行后如果方法被调用终端里会输出一棵调用树每个节点都有方法名、总耗时和自身耗时。我可以通过这棵树直接看到耗时的两个大头是数据库查询慢还是某个第三方外部接口慢又或者在本地坐着大量字符串处理。在实际排查中trace 遇到第三方 jar 包里的类也可以指定不限于项目自己的类。如果调用链特别深可以加 -n 限制追踪次数避免产生太多输出。3.6 内存与性能快照heapdump 和 profiler当怀疑内存泄漏时dashboard 只能看到整体增长趋势要想进一步分析最直接的就是生成堆转储文件heapdump /tmp/app-jvm.hprof生成后把 hprof 文件拿下来用可视化分析工具看大对象和引用链。如果怀疑 CPU 性能热点在哪个方法而不只是某条线程可以用 profiler 生成火焰图profiler start等采样一段时间后profiler stop --format html它会输出一个 HTML 火焰图能看到 CPU 时间都消耗在哪些方法栈上。和传统采样分析相比这种方式更直观尤其适合定位那种“很多线程都在执行同一段热点代码”的问题。3.7 mc redefine不重启的临时热修复这个能力很强但也要谨慎用。redefine 的思路是你可以在运行中的 JVM 里替换一个已加载类的字节码而不需要重启服务。完整的流程是先用 jad 导出源码然后用 mc 编译成字节码最后用 redefine 加载。比如jad --source-only com.example.demo.HelloService /tmp/HelloService.java在 Arthas 控制台里mc -d /tmp /tmp/HelloService.java编译成功后会得到一个 class 文件路径接着执行redefine /tmp/com/example/demo/HelloService.class这时线上方法体已经被替换成新逻辑。我用过一次临时止血一个空指针问题紧急出现当时发布流程来不及走完就差这么一次 redefine 让服务先恢复然后马上补正式版本。但要记住redefine 并不适合随意使用它有非常明确的限制。例如不能增加或删除字段、不能改变方法签名只能对方法体做有限的修改。它终究是应急手段不是长期热更新方案。另外生产环境使用前必须确认服务有回滚方案。4. 两个典型的线上故障复盘很多人学了 Arthas 命令后还是不知道从哪入手。我这里把两个最常见的故障场景从进场到定位再到收尾的完整流程走一遍供你参考。4.1 CPU 飙升从 dashboard 到代码行的标准路径某天下午某业务服务 CPU 突然 100%影响面持续扩大。我先拿到该服务的宿主机和 PID登录后用 Arthas 附带上进程第一件事就是敲 dashboard。dashboard 上出现了两个高 CPU 线程 ID我立刻用 thread -n 3 看 top 线程再通过 thread 42 查看对应堆栈。堆栈显示线程正在执行一个名为 QueryWorker 的类定位到具体行号后反编译对应类jad com.demo.biz.QueryWorker看到源码后发现循环里有一段字符串拼接的逻辑而这个拼接导致正则表达式每次执行都触发一次极端回溯数据量一旦超过某个阈值 CPU 就冲上去了。解决方式先用 redefine 对方法做了简化修复把正则替换成普通字符串判断服务 CPU 立刻降下来。随后补正式版本发布。整个过程用了不到二十分钟没有重启过一次服务。这个案例给我的感觉是不要一开始就怀疑框架或中间件Arthas 的排查路径一定是“全局到线程线程到代码代码到逻辑”每一步都有明确证据。4.2 接口响应变慢用 trace 拆掉耗时的黑盒另一个高频问题是接口 P50 正常P99 却高得离谱。这种场景下你很难靠日志还原一次慢请求的内部耗时。我处理过一个订单查询接口变慢的问题入口方法每次调用慢 800ms 到 2s 不等但没有任何超时日志。我先用 trace 命令追踪入口trace com.demo.api.OrderQueryController query #cost 500调用树拉出来以后发现耗时大部分不在服务内部逻辑而是在调用名为 external-price-api 的第三方接口上。继续下钻 trace又看到每次调用前都有一段多出来的 retry 等待。最终顺着代码判断是某个配置项超时时间设置不合理触发了不必要的重试。这个过程中我完全没改代码只靠 trace 一条命令就找到了“黑盒”里的真实耗时分布。后续把配置调优上线P99 立刻回落。4.3 堆内存持续增长和 GC 频繁CPU 高和接口慢之外内存问题也很常见。当 dashboard 显示老年代占用持续上涨且 GC 次数频繁我一般会用 heapdump 抓一份堆快照再配合对象统计查看大对象。如果暂时不能把 hprof 导出到本地分析可以先在 Arthas 里用查看某个类继续观察也可以用 dashboard 观察不同内存区域的变化趋势判断是正常的缓存增长还是泄漏。很多情况下堆转储手术刀一落下问题对象立刻现形。5. 常见的报错与避坑指南Arthas 很好用但生产环境里也容易遇到小坑。我整理了一个速查表覆盖大部分令人困惑的情况。现象可能原因解决办法启动时报错找不到 Java 可执行文件JAVA_HOME 未配置或 PATH 里没有 java显式指定 JAVA_HOME 或用绝对路径执行 java进程列表里看不到目标进程目标 JVM 与 Arthas 启动账号不一致或进程权限不足用目标进程相同用户运行 Arthas必要时用 sudoer但要谨慎attach 之后控制台无响应网络策略、端口冲突或 Agent 加载缓慢检查目标主机防火墙重启 Arthas boot 或用独立端口thread -n 3 出来一堆线程但找不到业务代码线程栈被框架、线程池封装堆栈最外层是线程池名字展开看栈里的自定义包名部分或用 jad 定位方法watch / trace 没有输出目标类不在默认类加载器或者方法重载参数未匹配先用 sc -d 查看类加载器 hash用 -c 指定类加载器redefine 后报错拒绝定义新类与旧类结构差异过大或者类已被其他 agent 修改尽量只改方法体避免增删字段、改方法签名长时间挂载后发现业务性能下降Arthas Agent 和观测命令产生了额外开销不用时执行 stop避免长期驻留5.1 关于生产环境的五条红线第一不要在高压时段长时间跑大范围 watch 或 trace。原则上只对特定方法、特定条件进行短时间采样用完立刻停。第二查询出的入参、返回值、反编译代码都可能包含业务敏感数据不要直接截屏外发。第三redefine 修改属于临时手段必须有正式版本跟进而且操作前留好日志和回滚准备。第四多实例部署时只修一个实例验证效果确认无误再逐步操作其余实例。第五拒绝带“灰色心态”使用 Arthas它只能用于你有权限诊断的系统切不可把它当成绕过访问控制的工具。6. 长期使用 Arthas 后沉淀下来的一些经验文章写到这里我想分享几点纯粹来自实战的体会。第一个是命令不重要排查思路才重要。很多人背了一堆命令真遇到问题时还是慌。我建议把 dashboard、thread、trace、jad 这四类命令练成肌肉记忆无论什么问题先走“全局看现象线程看位置代码看因果”的顺序而不是在命令列表里找灵感。第二个经验是“用完即走”。Arthas 虽然轻量但驻留一份 Agent 在目标 JVM 终归是额外的状态。我见过有同事挂了一整天之后忘了 stop第二天线上服务内存异常排查半天才发现是 Arthas 的 Agent 和增强逻辑还在参与类加载。所以我现在会在每次诊断结束后马上执行 stop并且结合运维平台对所有实例做一次 Arthas 探针检查。第三个经验是要会和现有监控体系配合使用。Arthas 是“显微镜”适合定位具体原因但它不具备长期监控能力。线上指标趋势还是要交给监控告警平台当告警触发后再靠 Arthas 降临现场做深入分析。两者不是替代关系而是接力关系。如果你想进一步扩展还可以试试 Arthas 的 Tunnel/WebConsole 能力把多个实例的诊断通道统一管理这样不用挨个登录服务器也能看到不同主机上 Arthas 的诊断结果。不过往远程控制方向走之前务必把权限控制、审计留痕都做好线上诊断的每一步操作都值得被记录、被审视。最后再说一个小技巧平时可以在本地随便写个 Java Demo然后故意让代码出现死循环、慢 SQL、内存增长等模拟故障再用 Arthas 从头到尾排查一遍。练上几次之后线上真出问题你会发现自己从“满脑问号”变成了“按流程走”。这种工具值得花一个下午认真尝一遍。
延伸阅读

更多相关文章

2026/10/19 8:50:45

基于YOLOv11的智能安防监控系统搭建实战

就从标题聊起吧。用YOLOv11搭一套安防监控系统,这事儿听起来像是个大工程,但拆开来看,核心就三件事:把视频流里的人准确认出来、判断他有没有异常行为、然后在出事的时候及时告警。这套东西落地之后,可以用在园区周界、…

2026/10/19 8:50:45

YOLOv5/8/10远程监控动物侵扰检测实战:完整复盘与部署踩坑

做“远程监控动物侵扰检测”这个毕设项目时,我踩过的坑比想象中多得多。这个题目听起来就是“用YOLOv5、YOLOv8、YOLOv10训练一个模型,识别监控画面里出现的动物并告警”,但真正动手做才发现,从数据集标注、模型选型、训练调参&am…

2026/10/19 8:50:45

Arch Linux 从 stable 切换到 LTS 内核完整指南与踩坑实录

用过 Arch 一段时间的人,迟早会遇到一次这样的时刻:pacman -Syu之后系统提示更新了内核,重启后 Wi-Fi 或显卡驱动开始闹脾气,或者某个外设直接“消失”。这时候最容易想到的补救方案,就是把内核从一直追最新的 stable …

2026/10/19 9:51:14

开源代码审查方案实战:基于GitLab CI与Reviewdog的自动化质量门禁

项目标题: "open-code-review"慢。先把话说清楚。我这边说的open-code-review,是我自己在团队内部牵头做的一套开源代码审查方案,不是某个商业平台的神秘内测项目,也不是某篇论文里的理想流程。它就是一套把代码审查从“口头提一嘴…

2026/10/19 9:51:14

库卡机器人对接商科焊机:Profinet配置与GSD文件导入全流程

简介:这份课程资源面向工业自动化工程师、机器人调试人员及焊接自动化学习者,聚焦库卡机器人与商科焊机之间基于Profinet的通信配置,解决设备互联、GSD文件导入与焊接参数协同等实际问题。资源包共4个文件,压缩后约3.51MB&#xf…

2026/10/19 9:51:14

Win32 GDI AlphaBlend像素级透明混合实战指南

简介:本资源是一份面向Windows桌面开发初学者与中级C程序员的AlphaBlend半透明绘制实战源码包,聚焦图形界面中位图透明叠加这一典型视觉效果实现。资源完整演示了如何通过Windows GDI API调用AlphaBlend函数,结合32位带Alpha通道位图、BLENDF…

2026/10/19 9:51:14

Win32 AlphaBlend半透明绘制实战指南:解决发灰、锯齿与卡顿

简介:本资源是一份面向Windows图形编程初学者与中级开发者的Alpha混合技术实践源码包,聚焦于使用Win32 API中的AlphaBlend函数实现位图半透明绘制,解决GUI界面中图像叠加、视觉融合等典型需求。压缩包共15个文件,含4个带Alpha通道…

2026/10/19 9:46:13

Python列表与字典的底层逻辑、复杂度对比与选型指南

写了这么多年Python,回头看看每天写在代码里的东西,出现频率最高的不是复杂的算法,也不是花哨的设计模式,而是最朴素的列表和字典。作为Python数据容器中的两大支柱,列表负责"按顺序装东西",字典…

2026/10/18 0:01:50

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/19 0:04:56

悟空开源无代码平台实战:从实体建模到应用设计避坑指南

简介:基于悟空开源无代码平台的多种应用设计源码,面向希望在不编写代码的情况下快速搭建CRM、HRM、财务系统、ERP、SRM等业务应用的企业与技术人员,通过拖放式界面和内置模板即可完成应用定制与部署。压缩包共697个文件,约10.74MB…

2026/10/19 0:04:56

基于.NET9的多租户权限系统:数据权限与动态API落地实践

简介:这份资源是一套面向 .NET 与 Vue 全栈开发者的中台权限管理系统,后端基于 .Net9,前端采用 Vue3 Element Plus,并配套 uniapp uviewui 移动端方案,实现前后端分离。系统覆盖多租户隔离、数据权限、动态 Api、任务…

2026/10/19 0:04:56

场地预约小程序毕设实战:SSM+微信小程序+MySQL数据库设计到避坑

简介:面向毕业设计场景的场地预约小程序完整项目,基于微信小程序SSMMySql技术栈开发,适合计算机相关专业学生作为选题参考、功能扩展或二次开发起点。系统实现场地类型管理、场地管理、预约管理、取消申请与押金退回等功能,分为管…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑