Java 线上监控诊断工具 Arthas

本文介绍由阿里开源的 Java 线上监控诊断工具 Arthas (阿尔萨斯)

[TOC]

安装

依赖:JDK 6 及以上

下载 Demo:

curl -O https://arthas.aliyun.com/math-game.jar
curl -O https://github.com/hengyunabc/spring-boot-inside/raw/master/demo-arthas-spring-boot/demo-arthas-spring-boot.jar
start java -jar math-game.jar
start java -jar demo-arthas-spring-boot.jar

Demo 源码:

快速安装,启动时会自动下载全量依赖到 ~/.arthas

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

全量安装,不需要在下载其他依赖,适合离线使用:

curl -O https://repo1.maven.org/maven2/com/taobao/arthas/arthas-packaging/3.6.7/arthas-packaging-3.6.7.jar

启动 Arthash:

java -jar arthas-boot.jar

启动后,Arthash 会创建两个目录:

  • ~/.arthas
  • ~/logs

退出会话,保持 Arthas 服务在后台运行:

quit | exit

退出并停止 Arthas 服务:

stop

卸载:

rm -rf ~/.arthas/
rm -rf ~/logs/arthas

Arthash 服务

执行 arthas-boot.jar 会启用 Arthas 服务,并提示与目标 Java 进程连接

Arthas 通过 JVM Attch 与目标进程进行通信,同时监听 telnet 和 http 端口等待客户端连接

Java 进程(JVM)<- JVM Attch <- Arthas Server(telnet 3658, http 8563) <- clinet

一个 Arthas 服务只能和一个进程连接,如果提示端口占用,需要先停止当前正在运行的服务,或选择其他端口

Arthas 默认只监听本地 IP,可以使用 --target-ip 指定监听地址:

java -jar arthash-boot.jar --target-ip 0.0.0.0

使用技巧

查看命令帮助:

# 查看所有命令
help

# 查看 watch 帮助信息
watch -h

通过 tab 键自动补全命令

管道:

thread 1 | grep 'main('

历史命令补全:

[输入一半的命令][↑ | ↓ ]

查看历史命令:

history

重定向:

jad --source-only demo.MathGame > MathGame.java

基本信息

系统实时数据面板:

dashbord

系统属性:

# 查看所有系统属性
sysprop

# 查看单个系统属性
sysprop key

# 设置系统属性
sysprop key value

环境变量:

# 查看所有环境变量
sysenv

# 查看单个环境变量
sysenv JAVA_HOME

JVM 信息

jvm

基础教程

线程:

# 列出所有线程
thread

# 查看线程的方法调用栈
thread 1

# 查找 main class
thread 1 | grep 'main('

# 查找死锁
thread -b

类信息:

# 查找已加载的类,支持通配符
# 如果输入的是接口,会显示接口的所有实现类
sc -d *MathGame

# 查找类的方法
sm -d demo.MathGame
sm -d demo.MathGame <init>

反编译:

jad demo.MathGame

jad --source-only demo.MathGame > MathGame.java

查看方法参数/返回值/异常信息:

# 通过 ognl 表达式组装返回值
watch demo.MathGame primeFactors '{params,returnObj,throwExp}'

# 展开返回值
watch -x 2 demo.MathGame primeFactors '{params,returnObj,throwExp}'

搜索内存对象:

vmtool --action getInstances --className demo.MathGame --limit 10

# 读取内存对象信息
vmtool --action getInstances --className demo.MathGame --express 'instances[0].illegalArgumentCount'

进阶教程

ognl 表达式:

# 查看静态变量
# 获取 ClassLoader HashCode
sc -d *UserController
ognl -c 38af3868 '@com.example.demo.arthas.user.UserController@logger'

# 调用静态方法
ognl '@java.lang.System@out.println("Hello World")'

常用 ognl 表达式

watch:查看方法调用的入参、返回值和异常

watch -n 3 com.example.demo.arthas.user.UserController findUserById '{params, returnObj, throwExp}'

# 只捕获由异常的方法调用
watch -n 3 -e com.example.demo.arthas.user.UserController findUserById '{params, returnObj, throwExp}'

# 对入参进行过滤
watch -n 3 com.example.demo.arthas.user.UserController findUserById '{params, returnObj, throwExp}' 'params[0] > 0'

# 捕获耗时超过 200 ms 的方法调用
watch -n 3 com.example.demo.arthas.user.UserController findUserById '{params, returnObj, throwExp}' '#cost > 200'

jad/mc/retransform:代码热更新

# 反编译
jad --source-only com.example.demo.arthas.user.UserController > UserContoller.java

# 内存编译
mc -c 38af3868 UserController.java

# 热更新
retransform -c 38af3868 'com\example\demo\arthas\user\UserController.class'

获取 Spring Context:

# 记录方法调用
tt -t -n 3 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHand lerMethod

# 获取 Spring Context
tt -i 1000 -w 'target.getApplicationContext()'

IDEA 集成

参考

  • https://arthas.aliyun.com/
  • https://arthas.aliyun.com/doc/arthas-tutorials.html