cxl
Published on 2025-06-04 / 54 Visits
0
0

Java应用诊断利器Arthas

在Java开发中,遇到线上问题时,传统的调试方式往往需要重启应用或修改代码,这不仅耗时且风险极高。阿里巴巴开源的Arthas​(Alibaba Java Diagnostic Tool)彻底改变了这一现状,它允许开发者在不重启应用、不修改代码的情况下,动态监控和诊断Java程序,成为生产环境问题排查的“瑞士军刀”。身为Java老鸟怎么能不知道它的用处呢,来一起康康玩玩吧!

什么是 Arthas?

Arthas 是阿里巴巴开源的一款 Java 诊断工具,旨在帮助开发者快速定位和解决生产环境中的问题。它采用命令行交互模式,提供了丰富的诊断命令,可以对类加载、线程、内存、方法调用等进行实时监控和分析。Arthas 的特点包括:

  • 无需重启:可以在不重启应用的情况下对运行中的程序进行诊断。

  • 实时监控:提供实时的性能数据和运行状态监控。

  • 强大的命令集:支持丰富的命令,涵盖了类、方法、线程、内存等多个方面。

  • 交互式界面:简单易用的命令行界面,支持自动补全和历史命令。

  • 在线文档:提供详细的文档和示例,帮助开发者快速上手。

为什么需要 Arthas?

在传统的 Java 开发中,调试往往需要在开发环境中重现问题,然后通过断点调试来定位问题。但在生产环境中,很多问题很难在开发环境中重现,而且直接在生产环境中使用传统的调试工具可能会影响服务的正常运行。Arthas 的出现解决了这些问题,最新版本已经更新到4.0.5,它可以在不影响服务正常运行的情况下,对生产环境中的问题进行实时诊断,大大提高了问题排查的效率。

使用

安装

前提是已安装了java环境,Arthas4支持jdk8版本及以上,若以下版本可使用Arthas3。

方法一

下载jar包并运行,由于我本地运行了三个java程序,所以会让我输入序号进入对应的java程序进行监控或诊断,我这里选择了2,进入之后我输入了dashboard 命令,默认会定时持续打印信息,可按ctrl+c退出,正确输出后就可以继续诊断了

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

方法二

Arthas 支持在 Linux/Unix/Mac 等平台上一键安装,请复制以下内容,并粘贴到命令行中,敲 回车 执行即可:

  curl -L https://arthas.aliyun.com/install.sh | sh

上述命令会下载启动脚本文件 as.sh 到当前目录,你可以放在任何地方或将其加入到 $PATH 中。

直接在 shell 下面执行./as.sh,就会进入交互界面。

也可以执行./as.sh -h来获取更多参数信息。

退出

如果只是退出当前的连接,可以用quit或者exit命令。Attach 到目标进程上的 arthas 还会继续运行,端口会保持开放,下次连接时可以直接连接上。如果想完全退出 arthas,可以执行stop命令。

Arthas 的核心功能

1. 类和方法监控

Arthas 可以监控类的加载情况和方法的调用情况,帮助开发者了解程序的运行状态。例如:

  • sc 命令可以查看 JVM 中已经加载的类。

  • sm 命令可以查看类的方法信息。

  • watch 命令可以监控方法的入参和返回值。

  • trace 命令可以跟踪方法调用的调用路径和耗时。

下面是一个使用 watch 命令监控方法调用的示例:

  watch com.example.demo.Service hello params returnObj

这个命令会监控 com.example.demo.Service 类中的 hello 方法,显示方法的入参和返回值。

2. 线程分析

线程问题是 Java 应用中常见的问题之一,Arthas 提供了丰富的线程分析功能:

  • thread 命令可以查看线程的状态和堆栈信息。

  • thread -b 命令可以找出阻塞其他线程的线程。

  • thread -n 3 命令可以查看最忙的 3 个线程。

例如,使用 thread -b 命令可以快速定位到导致线程阻塞的问题线程。

3. 内存分析

Arthas 可以帮助开发者分析内存使用情况,找出内存泄漏和高内存占用的问题:

  • heapdump 命令可以生成堆转储文件:heapdump --live /tmp/dump.hprof # 仅导出存活对象

  • ognl 命令可以执行 OGNL 表达式,查看对象的属性和方法。

  • logger 动态调整日志级别,无需重启应用即可修改日志配置:logger --name com.example -level DEBUG

4. 字节码增强

Arthas 支持字节码增强功能,可以在运行时修改类的行为,例如添加日志、统计方法调用时间等。这在不修改代码的情况下非常有用:

  • redefine 命令可以重新定义类。

  • jad 命令可以反编译类。

  • mc 命令可以编译 Java 文件。

例如,使用 jad 命令可以查看类的源代码:

  jad com.example.demo.Service

5. 其他功能

除了以上核心功能外,Arthas 还提供了许多其他实用的功能:

  • dashboard 命令可以查看应用的实时仪表盘,包括线程、内存、GC 等信息。

  • tt 命令可以记录方法调用的详细信息,支持回放。

  • monitor 命令可以监控方法的调用情况,包括调用次数、平均耗时等。

  • vmoption 命令可以查看和修改 JVM 参数。

Arthas的典型使用场景

场景1:生产环境紧急排查

当线上接口突然超时,通过以下步骤快速定位:

  1. 使用trace追踪接口方法调用链,发现某SQL查询耗时异常。

  2. 结合jad反编译相关类,确认SQL语句是否正确。

  3. redefine紧急修复SQL参数拼接问题。

场景2:性能优化

针对高并发系统的CPU飙升问题:

  1. dashboard发现某线程CPU占用100%。

  2. thread -n 5定位到问题线程,解析堆栈发现死循环。

  3. 通过tt录制方法调用上下文,复现问题并修复。

场景3:开发调试增强

本地开发时,无需添加冗余日志:

  1. watch实时观察方法参数,验证业务逻辑是否正确。

  2. 通过tt -t记录方法调用快照,回放请求以调试偶发问题。

场景4:线上应用突然响应变慢

某个线上应用突然响应变慢,用户请求处理时间明显增加,但没有明显的异常日志。

排查过程:

  1. 使用 dashboard 命令查看系统状态

  2. 首先使用 dashboard 命令查看应用的整体状态,发现 CPU 使用率很高,线程数也比平时多。

  3. 使用 thread 命令分析线程

    使用 thread -n 3 命令查看最忙的 3 个线程,发现有一个线程一直处于 RUNNABLE 状态,并且 CPU 使用率很高。进一步使用 thread [线程ID] 命令查看该线程的堆栈信息,发现该线程一直在执行某个方法。

  4. 使用 trace 命令跟踪方法调用

    使用 trace 命令跟踪该方法的调用路径和耗时,发现该方法内部调用了一个外部服务,并且调用时间很长。

  5. 使用 watch 命令监控方法入参和返回值

    使用 watch 命令监控该方法的入参和返回值,发现每次调用外部服务时,返回值都很大,可能存在数据量过大的问题。

  6. 定位问题

    通过以上分析,发现是由于外部服务返回的数据量过大,导致处理时间变长。进一步排查发现是查询条件没有正确传递,导致返回了大量不必要的数据。

注意事项

  1. 避免性能影响

    • 避免对高并发方法使用trace(可能导致方法执行变慢)。

    • 使用monitor时设置合理的统计周期(如-c 5表示每 5 秒统计一次)。

  2. 谨慎使用字节码增强

    • 避免在生产环境使用redefine命令修改类(可能导致 JVM 不稳定)。

    • 使用tt(时间隧道)记录方法调用时,限制记录次数(如-n 100)。

  3. 防止信息泄露

    • 避免使用watchtrace监控包含敏感信息的方法(如密码、用户数据)。

    • 诊断结束后及时退出 Arthas 会话,避免他人误操作。

  4. 备份和恢复

    • 在执行关键命令前,记录系统状态(如 JVM 参数、线程数)。

    • 若出现异常,立即退出 Arthas 并重启应用(如有必要)。

总结

Arthas 是一款功能强大、使用简单的 Java 诊断工具,可以帮助开发者快速定位和解决生产环境中的问题。通过本文的介绍,你应该对 Arthas 的基本功能和使用方法有了一定的了解。如果你还没有使用过 Arthas,建议在开发和测试环境中尝试一下,相信它会成为你开发过程中的得力助手。

附录

jvm 相关

  • dashboard - 当前系统的实时数据面板

  • getstatic - 查看类的静态属性

  • heapdump - dump java heap, 类似 jmap 命令的 heap dump 功能

  • jvm - 查看当前 JVM 的信息

  • logger - 查看和修改 logger

  • mbean - 查看 Mbean 的信息

  • memory - 查看 JVM 的内存信息

  • ognl - 执行 ognl 表达式

  • perfcounter - 查看当前 JVM 的 Perf Counter 信息

  • sysenv - 查看 JVM 的环境变量

  • sysprop - 查看和修改 JVM 的系统属性

  • thread - 查看当前 JVM 的线程堆栈信息

  • vmoption - 查看和修改 JVM 里诊断相关的 option

  • vmtool - 从 jvm 里查询对象,执行 forceGc

class/classloader 相关

  • classloader - 查看 classloader 的继承树,urls,类加载信息,使用 classloader 去 getResource

  • dump - dump 已加载类的 byte code 到特定目录

  • jad - 反编译指定已加载类的源码

  • mc - 内存编译器,内存编译.java文件为.class文件

  • redefine - 加载外部的.class文件,redefine 到 JVM 里

  • retransform - 加载外部的.class文件,retransform 到 JVM 里

  • sc - 查看 JVM 已加载的类信息

  • sm - 查看已加载类的方法信息

monitor/watch/trace 相关

  • monitor - 方法执行监控

  • stack - 输出当前方法被调用的调用路径

  • trace - 方法内部调用路径,并输出方法路径上的每个节点上耗时

  • tt - 方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测

  • watch - 方法执行数据观测


Comment