Arthas 怎么用?从安装到 watch 命令实战,线上排查不重启 JVM

简介: Java 线上突然报错却没打日志?本文带你用 Arthas 在不重启 JVM 的前提下,用 watch 命令实时抓方法出入参,10 分钟上手线上诊断

大家好,我是程序员天天困。

这是我的「Arthas 线上诊断实战」系列第 1 篇,整个系列计划写 8 篇,覆盖 watch、trace、vmtool、profiler、ognl 这些常用命令,最后落到字节码增强原理。想看系列的可以点个关注,断更不弃更。

假如线上一个接口返回值莫名其妙偏大,本地跑一遍完全复现不了。按老办法只能加日志、走测试、再灰度——一轮下来半天没了,问题还可能因为重启就消失。最好的办法是用 Arthas,一条 watch 命令贴上去,三分钟就能定位到问题

如果你也经常被「线上没日志、本地复现不了、又不能随便重启」这三件事卡住,这篇就把 Arthas 的入门姿势一次讲清楚:它是什么、怎么装、watch 命令怎么抓出入参。点个收藏,我们开始

一、Arthas 是什么

官方对它的定义是:

Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率。
——Arthas 官方文档·简介

Arthas(阿尔萨斯):Alibaba 开源的 Java 线上诊断工具,能在不重启 JVM、不改业务代码的前提下观察方法的出入参、异常、耗时和运行时状态。你可以把它理解为「给运行中的 JVM 外接一个仪表盘,不动它的内部运转就能看到哪不对」。

它是 Alibaba 开源的 Java 诊断工具,深受开发者喜爱。当你遇到下面这些束手无策的问题时,它能帮你解决:

  • 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
  • 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
  • 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
  • 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
  • 是否有一个全局视角来查看系统的运行状况?
  • 有什么办法可以监控到 JVM 的实时运行状态?
  • 怎么快速定位应用的热点,生成火焰图?
  • 怎样直接从 JVM 内查找某个类的实例?

Arthas 4.x 支持 JDK 8+,包括 JDK 17、JDK 21 和 JDK 25,支持 Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。

我自己的体感是,Arthas 对于 Java 后端,就像电工师傅手里的电笔——线上有没有问题、问题落在哪个方法,一搭就知道,不必为了排查把服务停了或重启。这个系列我会一篇一篇把常用命令过一遍,第一篇就从最常用的 watch 开始。

二、为什么需要 Arthas

本地开发环境访问不到生产环境,生产出了问题没法用 IDE 远程调试——何况调试会暂停所有线程,等于让服务停摆。想在测试或预发环境复现?有些问题跟环境强相关,复现不了,甚至一重启就消失。加日志排查又得走「测试→预发→生产」一整套,等发上去 JVM 一重启,现场可能就没了。

Arthas 解决的就是这个困局:在线解决生产问题,既不重启 JVM,也不改业务代码;以观察者身份介入,不暂停任何线程

三、动手前的准备:装 IDEA 插件

在用之前,先装一个 IDEA 插件,帮我们快速生成 Arthas 命令,省得手敲一长串类名方法名。

打开 IDEA 的 Settings → Plugins → Marketplace,搜 Arthas 即可找到。

装完之后,在任意一个方法上右键,菜单里会多出一组 Arthas 命令(watch、trace、stack 等),点一下就把对应命令复制到剪贴板。

四、启动 Arthas 并 Attach 到目标进程

插件装好,接下来启动 Arthas 本体。它就是一个可执行 jar,两行命令搞定:

curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar

启动之后,Arthas 会先检查当前机器上有哪些 Java 进程,列成一个带序号的清单:

Attach(附加连接):Arthas 通过 JVM 自带的 Attach API 把自己「挂」到目标 Java 进程上,注入一段诊断代码,从而观察方法调用。它走的是观察者模式,不会暂停线程,所以能在生产环境安全使用。你可以理解为「给运行中的 JVM 外接一个仪表盘,不动它的内部运转」。

直接输入目标进程对应的序号回车,Arthas 就会 Attach 上去:

输入序号后 Arthas 选中目标进程

Attach 成功后,命令行提示符会变成 [arthas@PID]$,意味着你已经在目标进程里了,可以开始下诊断命令。

五、watch 命令实战:揪出那个多 +1 的 bug

接下来用一个实际例子看 watch 到底怎么用。先看一段最简单的程序:

@RequestMapping(path = "/user/calculate", method = RequestMethod.GET)
public Integer calculate(@RequestParam Integer x,
                         @RequestParam Integer y,
                         @RequestParam(name = "op") String op) {
   
    return doCalculate(x, y, op) + 1;  // 玄机就在这一行
}

public int doCalculate(int x, int y, String op) {
   
    if ("add".equals(op))      return x + y;
    else if ("sub".equals(op)) return x - y;
    else if ("mul".equals(op)) return x * y;
    else if ("div".equals(op)) return x / y;
    else throw new UnsupportedOperationException("NotSupportOp" + op);
}

这个接口算 x 和 y 的运算结果。注意 calculate 第 5 行有个 bug:把 doCalculate 的结果又 +1 了。从调用方看结果就是错的,但逻辑一长,肉眼一行行看代码很难一眼定位。

用 Arthas,我们可以动态观察 doCalculate 的返回值,一步一步排查,根本不用改代码。

watch(方法观察命令):Arthas 的核心命令之一,在目标方法每次被调用时拦截,按你给的表达式打印入参、返回值或异常。你可以理解为「在方法门口装了个摄像头,谁进谁出、带了什么、摔没摔跤,全拍下来」。

在 IDEA 里对 doCalculate 方法右键 → Arthas → watch,会复制出这样一条命令:

复制出来的命令长这样:

watch com.ttk.controller.WebController doCalculate '{params,returnObj,throwExp}'  -n 5  -x 3

这条命令我详细拆开讲,每一段都别记错:

  1. watch —— 表示当前要用的命令是 watch。
  2. org.example.controller.WebController —— 目标类的全限定名。
  3. doCalculate —— 目标方法名。
  4. '{params,returnObj,throwExp}' —— 要观察的对象,用 OGNL 表达式包起来:
    • params 对应方法的入参集合;
    • returnObj 对应方法走完后的返回结果;
    • throwExp 对应方法抛出的异常对象。
      合起来就是对这个方法的出入参和异常一起做诊断。
  5. -n 5 —— 诊断的次数,比如只观察 5 次调用就自动退出。
  6. -x 3 —— 输出对象时展开的层级,这个不太好理解,后面单独用例子讲。

把这条命令复制到 Arthas 终端:

然后触发一次调用:

curl 'http://localhost:8080/user/calculate?x=1&y=2&op=add'

可以看到入参 x=1、y=2、op=add,返回值是 3,说明 doCalculate 本身的计算没问题;最后一个是 null,表示异常为 null,也就是没发生异常。

这时候我们再去 watch 外层的 calculate 方法:

watch com.ttk.controller.WebController calculate '{params,returnObj,throwExp}'  -n 5  -x 3

就会发现返回值赫然是 4。两边一对比,问题就在 calculate 多写的那个 +1 上——这样很快就能找到问题所在,没动一行业务代码。

六、异常观察:throwExp 不再是 null

上面我们看到,如果方法抛了异常,watch 也是能观察到的。

比如把请求的 op 换成 add2doCalculate 就会抛出 UnsupportedOperationException

这时候再 watch,你会发现第三个对象 throwExp 不再是 null 了,而是对应的异常对象加完整的堆栈信息。这就是 throwExp 的意义——正常时是 null,抛异常时给你完整的异常现场,不用再去翻日志。

七、-x 的用法:看穿嵌套 Map

回到最开始那条命令里的 -x

watch com.ttk.controller.WebController calculate '{params,returnObj,throwExp}' -n 5 -x 3

-x 表示展开的层级,直接讲不好理解,看个例子就懂了。假如有个参数嵌套很深的方法:

public Integer doCalculate2(Map<String, Map<Integer, Set<Integer>>> data) {
   
    for (Map.Entry<String, Map<Integer, Set<Integer>>> entry : data.entrySet()) {
   
        String op = entry.getKey();
        Map<Integer, Set<Integer>> value = entry.getValue();
        Map.Entry<Integer, Set<Integer>> data_op = value
                .entrySet().stream().findAny().get();
        int x = data_op.getKey();
        int y = data_op.getValue().stream().findAny().get();
        return doCalculate(x, y, op);
    }
    return 0;
}

遇到这种参数嵌套好几层的,直接 watch 一下:

watch com.ttk.controller.WebController doCalculate2 '{params,returnObj,throwExp}'  -n 5  -x 3

发送请求

curl 'http://localhost:8080/user/calculate2'

你会发现只能看到 Map 第一个 key 是啥,里面套的 Map 和 Set 全看不出来。这时候把 -x 调成 4:

就能看到前两层了,以此类推,-x 调得越大展开越深。一句话:-x 就是「你愿意看到第几层」

八、params 的操作:只看你想看的那一个

继续回到这条命令:

watch com.ttk.controller.WebController calculate '{params,returnObj,throwExp}' -n 5 -x 3

注意这里的 params 是 param 的复数——因为函数参数有很多个。如果我们只想看其中一个呢?

比如这个方法:

public int doCalculate(int x, int y, String op) {
   
    if ("add".equals(op))      return x + y;
    else if ("sub".equals(op)) return x - y;
    else if ("mul".equals(op)) return x * y;
    else if ("div".equals(op)) return x / y;
    else throw new UnsupportedOperationException("NotSupportOp" + op);
}

我只想看 op,很简单:

watch com.ttk.controller.WebController calculate '{params[2]}' -n 5 -x 3

params 本质是个数组,索引从 0 数起,0 就是第一个参数,1 是第二个,2 就是第三个,依此类推。

甚至你还可以在 params 上做一些简单的计算操作,比如观察这两个入参的和:

watch com.ttk.controller.WebController calculate '{params[0]+params[1]}' -n 5 -x 3

这就是 watch 的用法。稍微引申一下,watch 拿到的观察对象固定就三个:

  • params:方法被调用时传进来的参数,按数组形式组织;
  • returnObj:方法正常走完时返回的结果;
  • throwExp:方法如果抛了异常,这里就是那个异常。

围绕这三个对象,你还能塞进简单的表达式做运算,比如下钻取属性、对入参做加减、把两个对象拼一起看,日常排查里八九成的场景都能覆盖。

结语

Arthas 解决的就是「线上有现场、但不能动现场」这个死结,而 watch 是它最趁手的那把螺丝刀——一行命令,出入参异常全在眼前。这一篇我们摸了 watch 的皮毛,下一篇聊 trace,看怎么定位「一个请求里到底哪一行最耗时」。

本文基于 Arthas 4.x 官方文档与个人实践整理,命令参数以官方文档为准。


我是程序员天天困,持续分享编程干货。觉得有用的话记得点赞收藏和关注~也欢迎在评论区聊聊:你在线上排查 bug 时,被哪个「没打日志的角落」坑过最久。

相关文章
|
5天前
|
人工智能 安全 测试技术
|
7天前
|
云安全 人工智能 安全
阿里云 Agentic SOC 位居 IDC MarketScape安全运营智能体2026领导者类别
以 Agentic AI 重构安全运营闭环,阿里云云安全在产品能力与市场份额
1199 3
|
8天前
|
缓存 UED 开发者
Codex109天重置23次,明天还要再送一次
Codex近109天完成23次额度重置,7月14日将迎来第24次。Tibo高频响应用户反馈:优化GPT-5.6高消耗问题、补发失效福利、调整重置时间——形成“反馈→回应→修复→补偿”正向闭环,彰显以用户为中心的产品哲学。(239字)
763 12
|
1天前
|
人工智能 运维 数据挖掘
最新版通义千问(Qwen3.8-Max-Preview)功能介绍
2026年7月,阿里云通义千问正式对外开放**Qwen3.8-Max-Preview旗舰预览模型**,作为目前千问系列规格最高、综合性能最强的新一代万亿级AI模型,该模型搭载2.4T超大参数架构,是阿里云首款突破万亿参数的原生多模态旗舰模型,全面覆盖文本、图像、视频、文档多维度处理能力。相较于前代热门Qwen3.7-Max版本,本次预览版实现全方位跨越式升级,在真实工程开发、多智能体长周期任务、全链路办公自动化、海量数据分析等高阶场景中,综合能力已达到全球顶尖模型水准。现阶段该模型已正式开放抢先体验通道,依托阿里云百炼Token Plan、Qoder编码平台、QoderWork办公终端三大专属
1460 0
|
7天前
|
数据采集 机器学习/深度学习 人工智能
田间杂草定位与检测4200张YOLO智慧农业数据集分享
本数据集含4200张真实农田图像,YOLO格式,单类别(杂草)高质量标注,覆盖多作物、多光照、多生长阶段等复杂场景,专为智慧农业杂草检测与智能除草设备研发设计,支持YOLOv5/v8/v10等主流模型训练。
378 94
|
11天前
|
存储 人工智能 JSON
Qwen 本地部署搭配 ComfyUI 生成 AI 漫剧完整实操指南(小白零基础可落地,零成本无限生成+角色一致性天花板)
2026全网最优本地漫剧流水线:零成本、离线运行、角色统一、低配(8G显卡)可跑。融合Qwen本地大模型+ComfyUI双引擎,实现剧本生成→分镜绘图→动态成片全自动,隐私安全、无审核限流,新手30分钟上手,日更无忧。(239字)
|
2天前
|
人工智能
Qwen3.8抢先体验!正式版即将发布并开源!
千问Qwen3.8即将开源,参数达2.4T,进化速度以“天”计,实力媲美Fable 5。预览版Qwen3.8-Max已上线阿里Token Plan等平台,限时优惠:日间Credits低至1折,夜间更优,个人/团队版月付仅35元起!
399 15
|
5天前
|
Web App开发 数据采集 人工智能
|
6天前
|
人工智能 自然语言处理 云计算
2026阿里云大使招募:抢占AI先机,轻松赚取最高30%返佣,享官方全程陪跑支持!
阿里云2026云大使计划全新升级!无门槛加入,覆盖个人与企业。推广400+款产品(含热门MAAS产品,如秒悟、百炼等),享高额返佣+长周期收益。官方提供培训、方案落地、客户陪跑全链路支持,助你成为AI时代超级连接者。会分享,就能赚!