行业资讯
📅 2026/7/23 10:10:01
Arthas 概述:无需重启的线上诊断利器
Arthas 概述无需重启的线上诊断利器线上系统出现问题时传统的排查手段存在明显局限。加日志需要修改代码、提交、构建、部署整个流程耗时至少数十分钟而且重启会导致问题现场被破坏难以复现。Arthas 是阿里巴巴开源的 Java 诊断工具通过字节码增强技术可以在不重启 JVM、不修改代码的前提下实时查看方法调用信息、监控 JVM 状态、追踪调用链路。Arthas 的核心能力包括在线查看方法入参和返回值、反编译源码、监控方法执行耗时、追踪调用路径、热替换代码。其中 watch 命令是最常用的功能之一它可以直接观察指定方法的每一次调用包括入参、返回值和异常信息。---2. Arthas 的安装与快速启动2.1 下载与启动Arthas 是一个独立的 jar 包下载后直接通过 java 命令启动# 下载 arthas-boot.jar curl -O https://arthas.aliyun.com/arthas-boot.jar # 启动 Arthas自动列出当前机器上运行的所有 Java 进程 java -jar arthas-boot.jar启动后Arthas 会列出当前系统中的 Java 进程输入序号选择要诊断的目标进程。连接成功后进入 Arthas 的命令行交互界面。2.2 基于 Docker 环境的快速接入对于容器化部署的服务可以通过kubectl exec进入容器后下载并启动 Arthaskubectl exec -it order-service-7d4f8b9c6-xz2kq -- /bin/bash # 在容器内下载并启动 curl -O https://arthas.aliyun.com/arthas-boot.jar java -jar arthas-boot.jar选择 PID 为 1 的 Java 进程即可。对于基于 JRE 基础镜像的容器可能缺少 curl 命令可以在本地下载后通过kubectl cp拷贝到容器中。---3. watch 命令深度解析观察方法调用的神眼3.1 watch 命令的基本语法watch 类名 方法名 观察表达式 条件表达式类名全限定类名支持通配符。方法名方法名称支持通配符。观察表达式指定要查看的内容常用值为{params, returnObj, throwExp}。条件表达式过滤条件只有满足条件的调用才会输出。不指定则输出所有调用。3.2 查看方法入参和返回值这是最基础的使用场景在不加日志的情况下观察某个方法的实际调用情况。# 观察 OrderService.createOrder 方法的入参和返回值 watch com.example.service.OrderService createOrder {params, returnObj} -x 3params表示方法的所有入参。returnObj表示方法的返回值。-x 3指定输出结果中对象的展开深度为 3 层。如果不指定展开深度嵌套对象默认只显示第一层的引用地址。ClientOrderService目标 JVMArthas Agent运维人员ClientOrderService目标 JVMArthas Agent运维人员增强完成等待方法调用watch OrderService createOrder {params, returnObj} -x 3字节码增强在 createOrder 方法前后插入探针调用 createOrder(order, userId)触发探针记录 params执行业务逻辑触发探针记录 returnObj返回结果输出:params[Order{idnull, amount100}, 12345]returnObjOrderResult{code0, msg成功}3.3 watch 命令的输出格式说明Arthas 会将每次方法调用的观察结果格式化输出典型输出如下ts2024-01-15 14:30:25; [cost45ms] resultArrayList[ Object[][ Order[idnull,amount100.0,userId12345], String[normal], ], OrderResult[code0,msg创建成功,orderId98765], ]ts方法调用发生的时间戳。cost方法执行的耗时单位毫秒。result观察表达式求值的结果。外层数组的第一个元素是params第二个元素是returnObj。3.4 条件过滤精准捕获异常调用在生产环境中目标方法的调用频率可能非常高。输出所有调用会产生大量无效信息既刷屏又消耗 Arthas 的采样资源。条件表达式用于过滤出有诊断价值的具体调用。# 仅观察入参中金额大于 10000 的调用 watch com.example.service.OrderService createOrder {params, returnObj} params[0].amount 10000 -x 3 # 仅观察特定用户的调用 watch com.example.service.OrderService createOrder {params, returnObj} params[1].equals(12345) -x 3条件表达式使用 OGNL 语法可以访问入参、返回值、异常对象的属性。当方法有多个重载时条件表达式的参数索引与运行时实际传入的参数顺序一致。3.5 异常捕获在线定位报错的根本原因当线上偶尔抛出异常但日志不够详细时watch 命令可以直接捕获异常的完整堆栈信息。# 观察方法抛出异常时的入参和异常信息 watch com.example.service.OrderService createOrder {params, throwExp} -e -x 3-e参数表示仅在方法抛出异常时触发观察。throwExp代表异常对象。结合条件表达式可以进一步缩小范围# 仅在抛出特定异常类型时触发 watch com.example.service.OrderService createOrder {params, throwExp} \ throwExp instanceof java.lang.NullPointerException -e -x 3这个能力在生产故障排查中极具价值。当某个接口开始返回 500 错误但又无法从现有日志定位原因时通过-e参数可以直接抓取到异常发生时的完整调用上下文包括方法入参和异常堆栈。3.6 调用频率限制保护目标 JVM 的性能在高 QPS 的服务上使用 watch 命令如果不加限制会显著增加目标方法的执行开销。-n参数可以限制输出的次数# 仅输出前 5 次调用之后自动终止观察 watch com.example.service.OrderService createOrder {params, returnObj} -x 3 -n 5当-n次数达到后Arthas 会自动移除对该方法的字节码增强恢复原始性能。建议在初次使用 watch 时先设置较小的-n值确认过滤条件正确后再调整。---4. watch 命令的观察表达式详解观察表达式是 watch 命令最灵活的部分。它本质上是一个 OGNL 表达式Arthas 会将每次方法调用的上下文注入到表达式的求值环境中。4.1 内置变量列表| 变量名 | 说明 || :--- | :--- ||params| 方法的入参数组params[0]表示第一个参数。 ||returnObj| 方法的返回值。正常返回时有值抛出异常时为 null。 ||throwExp| 方法抛出的异常对象。正常返回时为 null。 ||target| 方法调用的目标对象即 this。 ||clazz| 目标对象的 Class 对象。 |4.2 构造自定义输出观察表达式可以构造自定义的数据结构来聚焦关注的信息# 仅输出入参的第一个参数和返回值的 code 字段 watch com.example.service.OrderService createOrder \ {params[0], returnObj.code} -x 2也可以在表达式中进行简单的计算和条件判断# 当返回值 code 不为 0 时输出入参和返回值 watch com.example.service.OrderService createOrder \ {params, returnObj} returnObj.code ! 0 -x 24.3 追踪方法内部耗时在观察表达式中可以使用#cost变量获取方法执行的总耗时# 输出方法入参和执行耗时 watch com.example.service.OrderService createOrder \ {params, #cost} params[0].amount 10000 -x 2#cost是 Arthas 注入的特殊变量表示当前调用从进入到返回的总耗时单位毫秒。这对于定位慢请求非常有效。---5. 基于 Arthas 的线上问题排查完整流程接口报错是否接口耗时变长是否逻辑结果不符合预期收到线上告警问题类型判断watch -e 抓取异常查看入参和异常堆栈定位异常原因是否入参异常导致?检查上游调用方修复入参问题根据异常堆栈定位代码 Bugwatch 观察耗时参数和耗时(含cost)耗时是否集中在特定入参?分析特定入参是否触发慢 SQL 或慢调用使用 trace 命令追踪内部调用链路耗时watch 观察入参和返回值参数和返回对象对比预期与实际定位逻辑分支使用 jad 反编译源码确认代码版本是否正确修复代码上线Arthas 的核心价值在于它提供了一个在线观察窗口。传统排查是“猜问题 - 加日志 - 重启 - 验证”的反复循环而 Arthas 将这个过程变为“观察现象 - 定位根因 - 一次修复”。每一次省去的重启都是对生产环境稳定性的保护。---6. Arthas 的其他常用命令速览watch 命令解决的是方法级别的入参和返回值观察但完整的线上诊断往往需要多个命令配合。6.1 trace 命令追踪方法内部调用路径与耗时trace com.example.service.OrderService createOrdertrace 会输出createOrder方法内部所有子调用的耗时树形图清晰展示每一层调用的时间占比。当 watch 确认了某个方法总体耗时异常后trace 用来向下钻取具体的耗时点。6.2 jad 命令在线反编译源码jad com.example.service.OrderService createOrderjad 直接反编译运行中的 class 文件输出 Java 源码。这对于验证部署的代码版本是否正确、确认线上实际运行的逻辑非常有帮助。如果怀疑回滚未生效或代码未同步jad 是最直接的验证工具。6.3 tt 命令方法执行数据时空隧道tt -t com.example.service.OrderService createOrdertt 是 Time Tunnel 的缩写。它会记录方法每次调用的入参、返回值、异常、耗时等完整信息并保存在一个时间碎片中。之后可以通过索引号随时回放某次调用的现场。tt 适合排查那些难以复现的偶发问题先在线上开启记录问题复现后再回放现场。6.4 dashboard 命令实时 JVM 监控面板dashboarddashboard 输出一个实时刷新的 JVM 监控面板包括线程使用情况、内存各区域占用、GC 次数和耗时、CPU 使用率等。这是接入 Arthas 后的第一个诊断动作用于快速判断 JVM 的整体健康状态。6.5 vmtool 命令强制 GC 和内存分析vmtool --action forceGc vmtool --action getInstances --className java.lang.String --limit 10vmtool 提供了对 JVM 内部的直接操作能力可以强制触发 GC或者查询堆中某个类的实例列表。---7. 生产环境使用 Arthas 的注意事项7.1 安全防护Arthas 默认监听 8563 端口仅允许本地 IP 127.0.0.1 连接。如果需要远程连接建议通过堡垒机的 SSH 隧道转发而不是直接开放端口。开放端口存在严重安全隐患攻击者可以通过 Arthas 执行任意 OGNL 表达式直接读取内存数据甚至修改运行时状态。7.2 性能影响评估Arthas 的字节码增强会为目标方法增加额外的执行指令。对于极高 QPS 的核心链路方法使用 watch 命令时务必设置-n限制输出次数并在排查完毕后通过stop命令移除增强或者直接quit退出 Arthas。watch 命令在输出大量匹配结果时I/O 操作会占用 JVM 线程资源。7.3 快速卸载Arthas 不会修改目标应用的代码文件所有的增强仅在内存中生效。退出 Arthas 时执行stop命令所有增强的类会被还原为原始字节码不会残留任何修改。如果 Arthas 进程异常退出增强的类会保持增强状态但只是多执行一些空逻辑不会影响业务正确性。# 安全退出 Arthas移除所有增强 stop---8. 实战案例在线定位订单创建接口异常背景订单服务的createOrder接口间歇性返回 500 错误错误日志中只记录了 NullPointerException但没有具体的空指针位置和触发入参。排查过程第一步使用 watch 命令开启异常捕获等待问题复现watch com.example.service.OrderService createOrder {params, throwExp} -e -x 3 -n 1几分钟后Arthas 捕获到一次异常调用ts2024-01-15 15:20:10; resultArrayList[ Object[][ Order[idnull,amount500.0,userId12345,itemListnull], ], java.lang.NullPointerException at com.example.service.OrderService.validateItems(OrderService.java:156) at com.example.service.OrderService.createOrder(OrderService.java:89) ]问题一目了然Order对象的itemList字段为 null导致validateItems方法抛出空指针。进一步检查上游调用方发现前端在某些场景下传入了空的商品列表。如果没有 Arthas排查这个问题的常规路径是加日志记录入参 - 提交代码 - 构建 - 部署 - 等待复现 - 看日志 - 定位原因。整个周期至少需要一次发布流程。而 Arthas 将这个过程缩短为一条命令耗时仅几分钟且无需任何发布和重启。耗时:数十分钟到数小时耗时:数分钟Arthas排查路径发现异常watch -e 抓取异常直接看到入参和堆栈修复代码传统排查路径发现异常添加日志代码提交 构建 部署等待问题复现查看日志定位修复代码修复上线修复上线watch 命令就像在代码中临时开了一扇窗户。不需要敲墙重装只需轻轻一推方法的内部世界便清晰可见。这是线上诊断中最高频、最实用的能力也是对“重启加日志”这种传统方式的一次彻底告别。