Arthas(阿尔萨斯)是阿里巴巴开源的Java诊断工具,支持JDK 6+,可在不修改代码、不重启服务的情况下,实时监控JVM状态、追踪方法调用、排查性能问题,被誉为“Java线上问题排查的瑞士军刀”。其核心优势在于非侵入式诊断,广泛应用于开发、测试及生产环境,尤其适合解决分布式系统中的疑难问题。
Arthas提供多种安装方式,适配Linux、Windows、MacOS及容器环境,以下为常用方法:
通过arthas-boot.jar
一键启动,适用于大多数场景:
# 下载arthas-boot.jar
curl -O https://arthas.aliyun.com/arthas-boot.jar
# 启动Arthas(需Java环境)
java -jar arthas-boot.jar
下载全量包解压后使用,包含完整工具链及离线文档:
# 下载全量包(以2025年最新版3.7.2为例)
wget https://arthas.aliyun.com/download/latest_version?mirror=aliyun -O arthas-packaging-3.7.2-bin.zip
# 解压并启动
unzip arthas-packaging-3.7.2-bin.zip
cd arthas-packaging-3.7.2-bin
java -jar arthas-boot.jar
在Docker/K8s中集成Arthas,可通过Dockerfile
预装或动态attach:
# Dockerfile示例:预装Arthas
FROM openjdk:8-jdk-alpine
ADD arthas-packaging-3.7.2-bin /opt/arthas
ENV PATH=$PATH:/opt/arthas/bin
启动Arthas后,会自动列出当前机器的Java进程,输入序号选择目标进程即可attach:
[INFO] Found existing java process, please choose one and hit RETURN.
* [1]: 12345 demo.MathGame # 目标进程PID及名称
[arthas@12345]$ # 成功进入交互界面
第一个命令:dashboard
输入dashboard
可实时查看JVM状态面板,包括线程、内存、GC等信息:
ID NAME GROUP PRIORITY STATE CPU% TIME INTERRUPTED DAEMON
17 pool-2-thread-1 system 5 WAITING 67 0:0 false false
27 Timer-for-arthas system 10 RUNNABLE 32 0:0 false true
...
按Q
或Ctrl+C
退出面板。
Arthas提供40+命令,覆盖JVM监控、线程分析、方法追踪等场景,以下为核心功能分类及示例:
命令 | 功能描述 | 示例 |
---|---|---|
dashboard |
实时数据面板(线程、内存、GC) | dashboard -i 2000 (每2秒刷新) |
jvm |
查看JVM详细信息(内存、GC算法、类加载) | jvm |
thread |
线程状态分析(定位CPU飙高、死锁) | thread -n 3 (显示最忙3个线程) |
memory |
JVM内存使用统计(堆、非堆、元空间) | memory |
示例:排查CPU飙高
# 查看CPU使用率最高的3个线程
thread -n 3
# 查看线程堆栈(假设线程ID为17)
thread 17
命令 | 功能描述 | 示例 |
---|---|---|
sc |
搜索已加载类(定位类冲突、加载路径) | sc -d com.example.UserService |
jad |
反编译类源码(验证线上代码是否最新) | jad com.example.UserService |
watch |
监控方法入参、返回值、异常 | watch com.example.UserService getUser "{params, returnObj}" -x 3 |
trace |
追踪方法调用链路及耗时(定位性能瓶颈) | trace com.example.OrderService createOrder "#cost > 100" (耗时>100ms) |
monitor |
统计方法调用次数、成功率、耗时 | monitor -c 5 com.example.PaymentService pay (每5秒统计) |
示例:监控方法入参和返回值
# 观察getUser方法的入参和返回值,展开深度3层
watch com.example.UserService getUser "{params, returnObj}" -x 3
命令 | 功能描述 | 示例 |
---|---|---|
profiler |
生成CPU/内存火焰图(可视化性能瓶颈) | profiler start && sleep 30 && profiler stop |
heapdump |
导出堆转储文件(分析内存泄漏) | heapdump /tmp/dump.hprof |
redefine |
热更新类字节码(紧急修复无需重启) | redefine /tmp/UpdatedClass.class |
ognl |
执行OGNL表达式(调用静态方法、修改变量) | ognl '@com.example.Config@MAX_RETRY=3' |
问题描述:生产环境服务响应缓慢,top
命令显示Java进程CPU使用率达100%。
排查步骤:
定位繁忙线程:
thread -n 3 # 显示CPU最高的3个线程
输出显示线程ID 17
占用CPU 90%,状态为RUNNABLE
。
查看线程堆栈:
thread 17 # 打印线程17的堆栈
发现线程卡在com.example.OrderService.calculatePrice()
方法。
追踪方法耗时:
trace com.example.OrderService calculatePrice # 追踪方法内部调用
结果显示calculatePrice()
中loopCalculate()
方法耗时占比95%,存在死循环。
解决方案:修复死循环逻辑,通过redefine
热更新代码验证。
问题描述:用户反馈“下单接口偶尔超时”,日志未记录关键参数。
排查步骤:
监控方法耗时:
monitor -c 10 com.example.OrderController createOrder # 每10秒统计
发现createOrder
平均耗时2.3秒,成功率98%。
追踪调用链路:
trace com.example.OrderController createOrder "#cost > 500" # 过滤耗时>500ms的调用
定位到checkInventory()
方法耗时1.8秒。
观察入参和返回值:
watch com.example.InventoryService checkInventory "{params, returnObj}" -x 2
发现部分商品ID入参为null
,导致数据库查询全表扫描。
解决方案:添加参数校验,过滤null
值,接口耗时降至200ms。
问题描述:生产环境日志级别为INFO
,需临时改为DEBUG
排查异常,但无法重启服务。
操作步骤:
反编译日志配置类:
jad --source-only com.example.LogConfig > /tmp/LogConfig.java
修改日志级别:
在LogConfig.java
中修改logger.setLevel(Level.DEBUG)
。
编译并热更新:
mc /tmp/LogConfig.java -d /tmp # 内存编译
redefine /tmp/com/example/LogConfig.class # 热更新类
验证:通过logger
命令确认日志级别已更新:
logger --name com.example.LogConfig # 显示当前级别为DEBUG
Arthas的强大功能依赖于Java底层技术,核心原理可概括为动态字节码增强+JVM Attach机制。
Arthas通过JVM的Attach API
(com.sun.tools.attach
)实现与目标进程的通信:
VirtualMachine.attach(pid)
连接到目标JVM,发送LOAD_AGENT
命令加载arthas-agent.jar
。agentmain
方法注入,创建自定义类加载器(ArthasClassLoader
)加载核心诊断逻辑,避免与应用类冲突。Arthas基于ASM框架动态修改类字节码,实现无侵入监控:
ClassFileTransformer
转换类文件,在目标方法前后插入监控逻辑(如watch
命令记录入参/返回值)。Instrumentation.retransformClasses()
重定义类,支持redefine
命令动态替换字节码(需遵循JVM规范,如不能新增字段/方法)。流程示例:
watch com.example.UserService getUser
命令;getUser
方法,插入参数捕获和日志输出逻辑;Instrumentation
提交给JVM,覆盖原类定义。Arthas采用C/S架构:
通过ognl
表达式和Linux管道组合命令,实现复杂诊断逻辑:
# 批量修改所有Logger级别为WARN
ognl '@org.slf4j.LoggerFactory@getLogger("root").setLevel(@ch.qos.logback.classic.Level@WARN)'
# 查找所有包含"Order"的类并反编译
sc -d *Order* | grep class-info | awk '{print $2}' | xargs jad
在Jenkins等工具中集成Arthas,实现发布前自动诊断:
// Jenkins Pipeline示例
stage('Arthas Check') {
steps {
sh 'java -jar arthas-boot.jar --target-ip 127.0.0.1 12345 -c "thread -b; jvm"'
}
}
通过Arthas Tunnel Server统一管理多台机器的Arthas实例:
java -jar arthas-tunnel-server.jar --server.port=8080
java -jar arthas-boot.jar --tunnel-server 'ws://tunnel-server-ip:8080/ws'
http://tunnel-server-ip:8080
)管理所有连接实例。使用profiler
命令生成CPU火焰图,直观定位热点方法:
profiler start --event cpu # 开始CPU采样
# 等待30秒...
profiler stop --format html # 生成火焰图(默认保存至arthas-output目录)
火焰图中,横向宽度代表CPU耗时,纵向代表调用栈,可快速识别耗时占比最高的方法。
问题现象 | 原因分析 | 解决方案 |
---|---|---|
Can not find java process |
目标进程未启动或用户无权限 | 确认进程PID存在,使用sudo 或与目标进程相同用户启动 |
AttachNotSupportedException |
JVM未启用Attach监听 | 添加JVM参数-XX:+StartAttachListener ,或重启目标进程 |
端口3658被占用 |
已有Arthas实例运行 | 执行stop 命令关闭旧实例,或指定新端口:java -jar arthas-boot.jar --telnet-port 9999 |
问题现象 | 原因分析 | 解决方案 |
---|---|---|
watch 命令无输出 |
方法未被调用或条件表达式错误 | 检查类名/方法名是否正确,简化条件表达式(如1==1 ) |
redefine 失败 |
字节码不兼容(如新增字段) | 确保修改仅涉及方法体,使用jad 反编译后对比原代码 |
中文乱码 |
系统编码非UTF-8 | 启动时指定编码:java -Dfile.encoding=utf-8 -jar arthas-boot.jar |
trace
/watch
等命令会增加方法调用耗时,建议高峰期避免全量监控,使用条件过滤(如#cost > 100
)。--username
/--password
启用认证,限制敏感命令(如redefine
)的使用。Arthas作为Java诊断领域的标杆工具,其实时性、非侵入性、功能全面性已得到业界广泛认可。无论是开发人员排查线上Bug,还是运维人员优化系统性能,Arthas都能大幅提升效率,避免“加日志-重启-复现”的低效循环。
未来展望:Arthas社区持续迭代,2025年版本已支持JDK 21、Docker/K8s原生集成,并计划引入AI辅助诊断功能。掌握Arthas不仅是解决当前问题的手段,更是深入理解JVM原理、提升架构能力的阶梯。
学习资源:
行动建议:从基础命令(dashboard
、thread
、watch
)开始实践,结合本文案例复现问题排查流程,逐步掌握高级功能。相信在未来的技术挑战中,Arthas会成为你不可或缺的诊断利器!