Arthas 简介及核心特点
Arthas 是阿里巴巴开源的 Java 应用诊断工具,用于实时在线监控和排查 Java 应用问题。它可以在不修改应用代码、无需重启的情况下,实时查看 JVM 的负载、内存、GC、线程等信息,并支持对业务级问题进行诊断。例如,可以查看方法的入参/返回值/异常信息、监测方法执行耗时、查询类加载情况等。Arthas 解决了许多线上难题(如类来自哪个 JAR、代码环境不匹配、定位实例对象、快速发现热点和生成火焰图等)。它支持 JDK6+,可在 Linux/Mac/Windows 上运行,以命令行交互形式工作,提供 Tab 自动补全等便利。
核心特点包括:
- 实时诊断:无侵入地接入运行的 JVM,动态观察应用状态。
- 丰富命令:支持查看线程、内存、类加载器等信息,生成方法执行日志、堆快照、火焰图等。
- 热更新能力:通过
jad
、redefine
等命令在线热加载代码和反编译源码。 - 排查利器:快速解决类冲突和定位类加载路径,支持 Web Console 等多种接入方式增强易用性。
Arthas 采用命令行交互模式,并内置 Web Console 和 IDEA 插件等多种使用方式,极大提升了线上问题排查效率。
功能详解
Arthas 提供了众多命令来诊断 Java 应用,这里对常用功能分类说明(命令示例中的 >
为 Arthas 提示符):
-
Dashboard:显示当前系统的实时数据面板(默认每秒刷新一次),包含线程、CPU、内存等信息。例如,在 Arthas 界面执行
dashboard
可实时查看各线程的 CPU 占用率、状态等(按Ctrl+C
退出面板)。 -
线程信息(thread):查看 JVM 当前所有线程及其堆栈。常用参数有
-n
(显示前 N 个最繁忙线程)和-b
(找出阻塞其他线程的线程)。例如执行thread -n 5
可列出最忙的 5 个线程及其堆栈,thread -b
可一键定位当前阻塞其他线程的线程。 -
类加载(classloader):查看 JVM 中各类加载器的继承树、加载的资源 URL 等信息。可用于快速解决类冲突问题并定位类加载路径。例如
classloader -t
显示类加载器层次结构,帮助判断类到底由哪个 ClassLoader 加载。 -
日志级别(logger):动态查看和修改日志配置(例如 logback、log4j 等 Logger)的级别。可以用
logger {loggerName}={LEVEL}
命令临时调整某个 Logger 的日志级别。例如在 Arthas 中执行logger com.example.service=DEBUG
可将com.example.service
的日志级别设置为 DEBUG,实时生效而无需重启。 -
堆快照(heapdump):生成 Java 堆的内存快照,类似于
jmap
的功能。例如执行:arthas@12345> heapdump /tmp/dump.hprof
Dumping heap to /tmp/dump.hprof … Heap dump file created ```
生成的 dump.hprof
文件可通过 Eclipse MAT 等工具分析,查找内存泄漏或大对象。使用 --live
参数可只转储存活对象。
-
方法监控(monitor):统计指定类或方法的执行情况,包括调用次数、平均耗时等。例如:
arthas@12345> monitor -c 5 demo.MathGame primeFactors
该命令每 5 秒收集 `demo.MathGame` 类中 `primeFactors` 方法的调用次数、平均时长等数据,持续监控并报告性能指标。
* **方法跟踪(trace)**:跟踪方法内部的调用链路,显示方法执行时的子调用路径及耗时。可以在调用链中插桩,帮助定位性能瓶颈和程序执行流程。
* **方法观察(watch)**:实时观察某个方法的执行信息,包括入参、返回值和抛出的异常。通过编写 OGNL 表达式,指定需要查看的变量。例如:
arthas@12345> watch demo.MathGame primeFactors ‘{params, returnObj, throwable}’
该命令在执行 `demo.MathGame.primeFactors()` 前后分别输出参数(`params`)、返回值(`returnObj`)和异常(`throwable`)等信息。
* **类反编译(jad)**:反编译 JVM 中已加载类的源码,用于快速查看类实现。执行 `jad com.example.MyClass` 即可打印出该类的 Java 源代码。
* **OGNL 表达式(ognl)**:在 JVM 中执行任意 OGNL 表达式,直接读取或修改对象属性,调用静态方法等。例如:
arthas@12345> ognl ‘@java.lang.System@out.println(“hello”)’
上述命令会直接调用 `System.out.println("hello")`。也可指定 ClassLoader 执行上下文,通过 OGNL 访问目标应用的静态字段和方法。
以上功能和其他命令(如 `sc`/`sm` 搜索类和方法、`memory` 查看内存使用情况等)结合使用,可以**大大提升线上问题的排查效率**。
## 安装与卸载步骤
* **Linux 系统**:推荐使用 Arthas-boot。一种方式是下载 `arthas-boot.jar`,然后执行:
```bash
$ curl -O https://arthas.aliyun.com/arthas-boot.jar $ java -jar arthas-boot.jar ```
根据提示选择要 attach 的 Java 进程编号,即可进入 Arthas 交互界面。另可使用一键安装脚本:
```bash
$ curl -L https://arthas.aliyun.com/install.sh | sh
脚本会下载 as.sh
启动脚本,可将其放入 $PATH
。退出 Arthas 交互界面可输入 quit
,它会将 Arthas agent 附加进程保留以便下一次使用。卸载 时,只需删除 Arthas 生成的运行目录:
$ rm -rf ~/.arthas/ ~/logs/arthas ```
即可完全移除 Arthas 文件。
* **Kubernetes 容器**:Arthas 可在容器中使用。常见做法包括:**复制到容器或镜像**——可以在镜像中预装 `arthas-boot.jar`,或者使用 Init Container 将 Arthas jar 复制到应用容器共享卷;**Sidecar/调试容器**——以 Sidecar 容器运行 Arthas,需共享主容器的 PID/网络命名空间(例如在 Pod Spec 中启用 `shareProcessNamespace`);**Kubectl exec**——直接通过 `kubectl exec -it <pod> -- sh` 进入应用容器后,执行 `java -jar arthas-boot.jar` 注入目标 Java 进程。例如:
```bash
$ kubectl exec -it myapp-pod -- java -jar /opt/arthas/arthas-boot.jar ```
上述命令会在指定 Pod 内启动 Arthas 并 attach Java 进程。新版本 Kubernetes 还支持 Ephemeral Container(调试容器),可临时为运行中的 Pod 注入一个具有 Arthas 的容器以进行诊断。
## 生产环境排查实践
在生产环境中,可利用 Arthas 对典型问题进行诊断,示例如下:
* **CPU 占用过高**:首先运行 `dashboard`,观察 CPU 和内存使用情况。排除过高的 GC 占用后,再使用 `thread -n`(或不带参数)找出 CPU 使用率最高的线程。然后执行例如 `thread -n 8` 查看这些线程的堆栈,定位耗时方法。按此思路,可逐步排查出导致 CPU 飙高的代码块或热点。
* **内存泄漏**:使用 `memory` 命令查看 JVM 各代内存占用,多次执行对比,确认是否有某个内存区域持续增长。若怀疑泄漏,可用 `heapdump` 生成堆快照(.hprof 文件)。示例:
arthas@12345> heapdump /tmp/dump.hprof
Dumping heap to /tmp/dump.hprof … Heap dump file created ```
然后使用 Eclipse MAT 等工具分析快照,查找数量持续增长或异常巨大的对象。结合多个时间点的堆快照比对,可以定位到具体泄漏的对象类和引用路径,有助于进一步代码修复。
-
线程死锁:应用无响应时,使用
thread -b
一键查找阻塞其他线程的“罪魁线程”。该命令会输出当前持有锁而导致其他线程等待的线程,便于发现死锁或锁竞争问题。例如:arthas@12345> thread -b
根据输出的信息,可进一步使用
thread
查看等待链或stack
查看锁定方法,进而定位死锁发生的代码位置。 -
日志级别动态调整:在排查问题时,可临时提升日志输出级别,无需重启应用。使用
logger
命令修改特定 Logger 的级别,例如:arthas@12345> logger com.example.service=DEBUG
该命令将
com.example.service
包下日志级别切换为 DEBUG。之后复现问题并观察日志输出,有助于定位问题。完成后可再将日志级别改回。 -
类加载问题:当遇到 NoSuchMethodError、ClassNotFoundException 等类加载相关异常时,可使用
classloader
、sc
(search class)等命令快速定位问题。Arthas 能“秒解类冲突问题,定位类加载路径”。例如通过classloader -t
查看加载器继承关系,再用sc User
查找是否有多个版本的User
类被加载。如果要查看某个类的源码,可用jad User
反编译,进一步确认加载源和版本差异。
Kubernetes 环境下的 Arthas 使用建议
在 Kubernetes 集群中使用 Arthas 时,可参考以下方式注入与操作:
-
Sidecar 容器:将 Arthas 放在与应用同一 Pod 的侧车容器中,启动时共享 Pod 的 PID Namespace;这样可直接通过 sidecar container 提供的终端或
kubectl exec
进入 sidecar 并对主容器进程进行诊断。 -
Init 容器:使用 Init Container 在应用启动前复制 arthas-boot.jar(或其他依赖)到应用容器的共享卷,确保主容器启动后已具备 Arthas 运行环境。
-
调试容器(Ephemeral Container):在 Kubernetes 1.18+ 中,可以通过
kubectl debug
添加临时容器与目标 Pod 共享命名空间,从而在调试容器中运行 Arthas,对目标应用进行诊断。 -
直接 Exec:如果应用容器镜像自带 JDK,也可直接使用
kubectl exec
进入容器并运行 Arthas;或者将arthas-boot.jar
放在 ConfigMap/镜像中,通过kubectl cp
复制到容器后执行。例如:$ kubectl exec -it mypod -- sh $ java -jar /opt/arthas/arthas-boot.jar ``` 即可为该容器内的 Java 进程注入 Arthas。
以上方法可根据实际权限和镜像环境选择使用。在 Kubernetes 中使用 Arthas 时,需注意应用是否以 PID 1 运行(如果是 init 进程,可能导致 attach 失败,可考虑在容器中使用 tini
等 Init 进程来使 Java 进程不再为 PID 1,以保证 attach 成功)。
实际案例
-
慢响应服务追踪:假设某接口响应缓慢,可在接口对应的方法上使用
monitor
或trace
。例如对UserService.getUser()
方法执行monitor UserService getUser -b 5
或trace UserService getUser
,查看该方法的调用次数和耗时情况,分析是否存在性能瓶颈或热点调用链路。发现耗时点后,再结合堆栈信息进行代码优化或逻辑调整。 -
定位内存泄漏对象:当发现内存持续上升时,可结合多次
heapdump
快照进行对比。例如每隔一定时间生成堆转储文件,然后用 MAT 对比分析,查找某个类的实例数或占用持续增多的情况。确定问题类后,可追溯代码查找未释放资源或缓存过大的原因并修复。 -
动态开启调试日志:遇到难以复现的问题时,可在 Arthas 中动态调整日志级别。比如在问题模块所在的包上执行
logger com.example.service=DEBUG
开启调试日志,复现问题后通过日志定位问题发生原因;问题排查完毕后再恢复原有日志级别。
以上示例结合 Arthas 的实时代码观察和分析能力,可帮助运维和开发人员在生产环境中快速定位和解决问题。
除了 Arthas,还有不少优秀的 Java 应用诊断和性能分析工具,适用于不同场景如本地开发调试、线上生产排查、性能压测、内存分析等。以下是一份常见工具的对比列表:
🛠️ 类似 Arthas 的 Java 诊断工具对比
工具名称 | 开发方 | 使用场景 | 主要功能 | 是否侵入式 | 是否适合线上 |
---|---|---|---|---|---|
Arthas | 阿里巴巴 | 线上+本地 | 方法跟踪、日志级别调整、内存、线程、类加载分析、OGNL 执行等 | 非侵入式 | ✅ 极适合 |
JFR (Java Flight Recorder) | Oracle/OpenJDK | 线上性能分析 | JVM 事件记录(GC、线程、锁、IO等)、性能剖析 | 非侵入式 | ✅(JDK 自带) |
Async-profiler | 开源 | CPU/内存分析 | 生成火焰图、支持采样分析、低性能开销 | 非侵入式 | ✅(适合低开销场景) |
BTrace | 开源 | 代码插桩 | 动态插入跟踪代码、监控方法调用 | 侵入式(运行期插桩) | ⚠️ 有一定风险 |
Greys/Greys-anatomy | 京东开源 | 动态诊断 | 类似 Arthas 的命令行诊断(停止维护) | 非侵入式 | ✅(但已过时) |
jstack / jmap / jcmd | Oracle/OpenJDK | 线程/堆分析 | 线程栈、堆快照、GC触发、类信息查看等 | 非侵入式 | ✅(标准工具) |
VisualVM | Oracle(已开源) | 图形界面分析 | 内存、线程、GC、类加载、JMX监控 | 非侵入式 | ✅(需开启 JMX) |
YourKit / JProfiler | 商业软件 | 全方位分析 | CPU、内存、线程、数据库、网络分析 | 非侵入式 | ✅(但付费) |
Perf (Linux) | Linux 工具 | 原生性能剖析 | 系统调用跟踪、JVM 级火焰图(结合 perf-map-agent) | 非侵入式 | ✅(但较复杂) |
✅ 场景建议
目标 | 推荐工具 |
---|---|
线上运行期诊断 | Arthas、JFR、Async-profiler、jstack、jmap |
生成火焰图 | async-profiler + Flamegraph、perf |
内存泄漏分析 | jmap + MAT、JProfiler、YourKit |
线程死锁/阻塞排查 | Arthas(thread/stack)、jstack、VisualVM |
动态调试代码逻辑 | Arthas(watch/trace/ognl)、BTrace |
开发调试阶段 | VisualVM、JProfiler、YourKit、Arthas(本地 attach) |
🔍 实战推荐组合
-
线上生产问题排查组合:
-
Arthas
(最灵活)jstack
+jmap
+JFR
-
async-profiler
火焰图 -
本地性能优化组合:
-
JProfiler
或YourKit
-
VisualVM
-
JFR + async-profiler