Arthas(阿尔萨斯) 是阿里巴巴于 2018 年开源的 Java 诊断利器。作为 GitHub 国产 Top5 的 Java 开源项目,已成为商业公司实际上的线上问题排查的首选工具。
Arthas 的核心优势在于:
- 无需重启应用:通过 Java Agent 动态 attach 到目标 JVM。
- 零代码侵入:不需修改业务代码即可完成诊断。
- 功能全面:覆盖类加载、方法追踪、线程分析、内存监控、动态执行等场景。
- 交互友善:支持命令行 + Web Console 双模式,学习成本低。
本文将详细解析 Arthas 的使用。
本文基于 Arthas 4.10.5 编写。
一、Arthas 快速上手
1.1 安装方式
方式一:在线一键安装(推荐)
# 使用Http1.0请求
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
执行后,Arthas 会自动列出当前主机所有可 attach 的 Java 进程:
[INFO] arthas-boot version: 4.10.5
[INFO] Found existing java process, please choose one and input the serial number of the process, eg: 1. Then hit ENTER.
* [1]: 12345 org.apache.catalina.startup.Bootstrap
[2]: 67890 com.example.MyApplication
输入序号(如 2),即可连接到目标进程。
方式二:手动下载完整包
适用于无外网环境:
wget https://arthas.aliyun.com/download/latest_version?mirror=aliyun -O arthas.zip
unzip arthas.zip
cd arthas
./as.sh
方式三:Maven 依赖(用于集成测试)
<dependency>
<groupId>com.taobao.arthas</groupId>
<artifactId>arthas-agent-attach</artifactId>
<version>4.10.5</version>
</dependency>
1.2 启动参数详解
|
参数 |
说明 |
默认值 |
|
–target-ip |
监听 IP |
127.0.0.1 |
|
–telnet-port |
Telnet 端口 |
3658 |
|
–http-port |
HTTP/WebConsole 端口 |
8563 |
|
–tunnel-server |
Tunnel Server 地址 |
无 |
|
–app-name |
应用名称(用于 Tunnel) |
无 |
示例:开放远程访问
java -jar arthas-boot.jar --target-ip 0.0.0.0 --telnet-port 3658 --http-port 8563
⚠️ 生产环境提议限制 IP 访问,避免安全风险。
1.3 连接方式
- 本地连接:直接运行 java -jar arthas-boot.jar
- 远程连接:telnet <服务器IP> 3658
- Web Console:浏览器访问 http://<服务器IP>:8563
Web Console 支持语法高亮、命令历史、多标签页,适合复杂操作。
二、基础命令与信息查看
2.1 协助与会话管理
|
命令 |
作用 |
|
help |
显示所有命令协助 |
|
help <command> |
查看具体命令用法 |
|
version |
显示 Arthas 版本 |
|
session |
查看当前会话 ID、启动时间等 |
|
quit / exit |
退出当前会话(Arthas 仍在后台运行) |
|
stop |
彻底关闭 Arthas(卸载 agent) |
2.2 JVM 全景监控:dashboard
dashboard
输出包含:
- Memory:堆/非堆内存使用情况
- GC:Young GC / Full GC 次数与耗时
- Threads:线程总数、活跃数、Daemon 数
- Runtime:JVM 启动时间、Uptime
- Class Loading:已加载类数量
按 Ctrl+C 退出实时刷新。
2.3 线程分析:thread
基础用法
thread # 列出所有线程
thread <id> # 查看指定线程堆栈
高级选项
|
选项 |
说明 |
|
-n N |
显示 CPU 使用率 top N 的线程 |
|
-b |
检测死锁(BLOCKED 状态线程) |
|
-i <ms> |
指定采样间隔(默认 100ms) |
实战示例:
# 找出 CPU 占用最高的 3 个线程
thread -n 3
# 检查是否存在死锁
thread -b
输出示例:
"Thread-5" Id=25 cpuUsage=85.2% RUNNABLE
at com.example.CpuBurner.run(CpuBurner.java:15)
2.4 JVM 详细信息:jvm
jvm
展示:
- JVM 版本、供应商
- 启动参数(-Xmx, -XX:+UseG1GC 等)
- 内存池详情(Eden、Survivor、Old Gen)
- GC 统计
- 系统属性(java.home, user.dir)
2.5 系统属性与环境变量
sysprop # 查看所有系统属性
sysprop java.version # 查看 JDK 版本
sysenv # 查看环境变量
sysenv PATH # 查看 PATH
支持动态修改(慎用):
sysprop user.timezone Asia/Shanghai
2.6 JVM 启动参数:vmoption
vmoption # 查看所有 JVM 选项
vmoption PrintGC # 查看 -XX:+PrintGC 是否开启
vmoption PrintGC true # 动态开启(部分参数支持)
注意:并非所有参数都支持运行时修改。
三、类与类加载器操作
3.1 搜索类:sc(Search Class)
sc *UserController # 模糊匹配
sc -d com.example.UserDao # 显示详细信息(类加载器、位置等)
sc -E "com.example..*Service" # 正则匹配
常用选项:
- -d:显示详细信息
- -E:启用正则表达式
- -c <hash>:指定类加载器 hashcode(用于多 ClassLoader 场景)
3.2 搜索方法:sm(Search Method)
sm com.example.UserService # 列出所有方法
sm com.example.UserService getUserById # 查看特定方法签名
sm -d com.example.UserService getUserById # 显示方法描述符
3.3 反编译:jad
ounter(line
jad com.example.UserService
输出反编译后的 Java 源码,便于理解线上代码逻辑。
若类被混淆或加密(如商业软件),可能反编译失败。
3.4 类加载器分析:classloader
ounter(lineounter(lineounter(lineounter(lineounter(line
classloader # 显示类加载器树
classloader -l # 列出所有类加载器
classloader -t # 以树形结构展示
classloader -c <hash> # 查看指定加载器加载的资源
classloader -a # 列出所有加载的类(慎用,可能卡顿)
典型场景:排查 ClassNotFoundException 或类版本冲突。
四、方法监控与动态追踪(核心功能)
4.1 watch:观察方法入参、返回值、异常
语法
ounter(line
watch <class> <method> '<express>' [condition] [options]
表达式变量
|
变量 |
含义 |
|
params |
参数数组 |
|
target |
当前对象 |
|
returnObj |
返回值 |
|
throwExp |
抛出的异常 |
|
#cost |
方法执行耗时(微秒) |
示例
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
# 观察 getUser 方法的入参和返回值
watch com.example.UserService getUser '{params, returnObj}' -x 2
# 仅当 userId > 1000 时触发
watch com.example.UserService getUser '{params[0]}' 'params[0] > 1000'
# 包含异常情况
watch com.example.UserService getUser '{throwExp}' -f -x 3
选项说明:
- -x N:展开对象层级(默认 1,提议 2~3)
- -f:包含异常(默认只成功调用)
- -s:打印调用栈
- -n N:执行 N 次后自动退出
4.2 trace:追踪方法调用路径与耗时
trace com.example.OrderService createOrder
输出示例:
+---[0.56ms] com.example.OrderService:createOrder()
+---[0.21ms] com.example.InventoryService:checkStock()
+---[0.30ms] com.example.PaymentService:processPayment()
+---[0.15ms] com.example.ThirdPartyClient:call()
用途:定位性能瓶颈,识别慢方法。
高级用法:
# 追踪子方法(默认只一层)
trace -E com.example.*Service .* # 正则匹配多个类方法
# 限制耗时 > 10ms 才输出
trace com.example.Service method '#cost > 10000'
4.3 monitor:统计方法调用指标
monitor -c 5 com.example.CacheService get
每 5 秒输出一次统计:
timestamp class method total success fail avg-rt(ms) fail-rate
-----------------------------------------------------------------------------------------------
2025-12-15 22:00:00 CacheService get 120 118 2 3.2 1.67%
适用于监控接口稳定性。
4.4 stack:打印方法调用栈
stack com.example.UserService updateUser
当 updateUser 被调用时,立即打印完整调用栈,用于定位“谁调用了我”。
五、高级功能与动态干预
5.1 OGNL 表达式:动态执行代码
OGNL(Object-Graph Navigation Language)允许在运行时执行任意 Java 表达式。
基础用法
# 调用静态方法
ognl '@java.lang.System@out.println("Hello")'
# 获取静态字段
ognl '@com.example.Config@MAX_RETRY'
# 修改静态变量(慎用!)
ognl '@com.example.FeatureToggle@setEnabled(true)'
Spring 应用中获取 Bean
ounter(line
ognl '#ctx=@org.springframework.context.support.AbstractApplicationContext@getBean("applicationContext"), #ctx.getBean("userService")'
提示:可通过 sc *ApplicationContext 找到实际上下文类名。
5.2 日志级别动态调整:logger
支持 Logback、Log4j2、JUL。
logger # 查看所有 logger
logger --name ROOT --level DEBUG # 设置根日志为 DEBUG
logger --name com.example --level WARN
无需重启即可开启 debug 日志,排查问题后恢复。
5.3 热更新类:mc + redefine(高危操作!)
仅限开发/测试环境使用!
步骤:
- 修改源码(如修复 bug)
- 编译 .class 文件
- 使用 Arthas 内存编译器(mc)或上传 .class
- redefine 替换
# 方式一:使用 mc 编译(需源码)
mc /tmp/UserService.java -d /tmp
redefine /tmp/com/example/UserService.class
# 方式二:直接上传 .class 文件
redefine /opt/fix/UserService.class
限制:
- 不能增减字段/方法
- 不能修改方法签名
- 不支持 Lambda、内部类复杂结构
5.4 异步与批处理
- 后台执行:trace Xxx method &
- 限制次数:watch Xxx method -n 10
- 重定向输出(Web Console 支持保存结果)
六、生产环境实战案例
C1:CPU 使用率飙升至 100%
排查步骤:
- dashboard → 确认 CPU 高
- thread -n 3 → 找出高 CPU 线程
- thread <tid> → 查看堆栈
- jad + trace → 定位具体方法
- 发现死循环或正则回溯等问题
解决方案:
- 优化算法
- 增加超时控制
- 修复正则表达式
C2:接口响应时间从 50ms 升至 2s
排查步骤:
- trace com.xxx.Controller handleRequest
- 发现 PaymentService.callThirdParty() 耗时 1800ms
- watch PaymentService callThirdParty '{params, #cost}'
- 发现第三方 API 未设置超时
解决方案:
- 添加 HttpClient 超时配置
- 增加重试机制
C3:偶发 NullPointerException
排查步骤:
- watch Xxx method '{params, throwExp}' -f -x 3
- 捕获到异常时的参数状态
- 发现某字段为空,因上游未校验
解决方案:
- 增加空值校验
- 完善单元测试
C4:动态开启调试日志
logger --name com.example.payment --level DEBUG
# 复现问题后
logger --name com.example.payment --level INFO
避免重启,快速获取上下文日志。
七、安全、性能与最佳实践
7.1 安全注意事项
- 权限控制:Arthas 进程必须与目标应用同用户
- 网络暴露:生产环境禁止 –target-ip 0.0.0.0,应通过 SSH 隧道访问
- 高危命令:
- ognl:可能执行任意代码
- redefine:可能导致 JVM 崩溃
- vmoption:可能影响 GC 行为
- 审计:提议记录 Arthas 操作日志(可通过 Web Console 集成)
7.2 性能影响评估
|
命令 |
性能影响 |
提议 |
|
watch /trace |
中(字节码增强) |
加 -n 限制次数 |
|
jad |
低 |
无 |
|
thread -n |
低 |
无 |
|
classloader -a |
高(遍历所有类) |
避免使用 |
|
redefine |
高(类重定义) |
仅测试环境 |
7.3 最佳实践
- 先观察,再干预:优先使用 dashboard、thread、trace 等只读命令。
- 限制范围:使用 -n、条件表达式缩小监控范围。
- 及时退出:长时间运行的 watch/trace 会持续占用资源。
- 结合日志:Arthas 与应用日志互补,共同定位问题。
- 团队共享:通过 Web Console 或 Tunnel Server 实现多人协作。
八、扩展与生态
8.1 Tunnel Server:聚焦管理
适用于大规模集群:
- 启动 Tunnel Server(官方提供 Docker 镜像)
- 客户端启动时指定 –tunnel-server ws://tunnel.example.com:7777
- Web UI 统一管理所有 Arthas 实例
8.2 与 SkyWalking、Prometheus 集成
- Arthas 本身不提供指标上报,但可通过脚本定期采集 dashboard 数据
- 结合 jmx_exporter 实现 JVM 指标监控
8.3 自动化脚本
编写 Arthas 脚本(.arthas 文件):
# diagnose.arthas
dashboard
thread -n 3
sc *Controller
执行:
java -jar arthas-boot.jar -f diagnose.arthas
结语
Arthas 作为一款强劲的 Java 诊断工具,其价值不仅在于功能丰富,更在于它改变了我们排查线上问题的思维方式——从“被动等待日志”转向“主动实时观测”。掌握 Arthas,意味着你拥有了在不重启、不改代码的前提下,深入 JVM 内部的能力。
不过,能力越大,责任越大。务必牢记:生产环境谨慎操作,安全第一。
附录:常用命令速查表
|
场景 |
命令 |
|
查看整体状态 |
dashboard |
|
CPU 高 |
thread -n 3 |
|
死锁 |
thread -b |
|
反编译 |
jad com.xxx.Class |
|
观察方法 |
watch Xxx method '{params, returnObj}' -x 2 |
|
追踪耗时 |
trace Xxx method |
|
统计调用 |
monitor -c 5 Xxx method |
|
谁调用了我 |
stack Xxx method |
|
动态日志 |
logger –name xxx –level DEBUG |
|
执行代码 |
ognl '@System@out.println(“test”)' |





