Arthas
Arthas是一款线上监控诊断产品,通过全局视角实时查看应用load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率.
https://github.com/alibaba/arthas
测试代码
|
|
附加进程
- 启动Demo
- 执行arthas-boot.jar进行附加
|
|
如果提示端口被占用,可以使用下述命令进行端口自定义.
|
|
如果附加成功,Arthas会在下述目录进行日志记录.
|
|
- 通过浏览器连接Arthas
Arthas目前支持Web Console,用户在attach成功之后,可以直接访问:http://127.0.0.1:3658/
默认情况下,Arthas只listen 127.0.0.1,所以如果想从远程连接,则可以使用–target-ip参数指定listen的IP
基础命令
基础命令 | 说明 |
---|---|
base64 | base64编码转换.同Linux base64 |
cat | 打印文件内容.同Linux cat |
cls | 清空当前屏幕区域 |
echo | 打印参数.同Linux echo |
grep | 匹配查找.同Linux grep |
help | 查看命令帮助信息 |
history | 打印命令历史 |
keymap | 显示所有的快捷键 |
pwd | 显示当前的工作路径.同Linux pwd |
quit | 退出当前Arthas客户端,其他Arthas客户端不受影响 |
reset | 重置增强类,将被Arthas增强过的类全部还原,Arthas服务端关闭时会重置所有增强过的类 |
session | 查看当前会话信息 |
stop | 关闭Arthas服务端,所有Arthas客户端全部退出 |
tee | 复制标准输入到标准输出和指定的文件.同Linux tee |
version | 输出当前目标Java进程所加载的Arthas版本号 |
JVM命令
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命令
类,类加载相关的命令 | 说明 |
---|---|
sc | 查看JVM已加载的类信息 |
sm | 查看已加载类的方法信息 |
jad | 反编译字节码为源代码 |
mc | 内存编译器,内存编译.java文件为.class文件 |
redefine | 加载外部的.class文件,redefine到JVM里 |
retransform | 加载外部的.class文件,retransform到JVM里(推荐) |
dump | dump已加载类的byte code到特定目录 |
classloader | 获取类加载器信息 |
sc
查看JVM已加载的类信息,“Search-Class"的简写,这个命令能搜索出所有已经加载到JVM中的Class信息.
sc默认开启了子类匹配功能,也就是说所有当前类的子类也会被搜索出来,想要精确的匹配,可以执行下述命令.
|
|
参数说明如下:
参数名称 | 参数说明 |
---|---|
class-pattern | 类名表达式匹配,支持全限定名,如com.luohun.test.AAA,也支持com/luohun/test/AAA这样的格式 |
method-pattern | 方法名表达式匹配 |
[d] | 输出当前类的详细信息,包括这个类所加载的原始文件来源、类的声明、加载的ClassLoader等详细信息. 如果一个类被多个ClassLoader所加载,则会出现多次 |
[E] | 开启正则表达式匹配,默认为通配符匹配 |
[f] | 输出当前类的成员变量信息(需要配合参数-d一起使用) |
示例命令如下:
|
|
sm
查看已加载类的方法信息,“Search-Method"的简写,这个命令能搜索出所有已经加载了Class信息的方法信息.但是只能看到由当前类所声明(declaring)的方法,父类则无法看到.
参数说明如下:
参数名称 | 参数说明 |
---|---|
class-pattern | 类名表达式匹配 |
method-pattern | 方法名表达式匹配 |
[d] | 展示每个方法的详细信息 |
[E] | 开启正则表达式匹配,默认为通配符匹配 |
示例命令如下:
|
|
jad
反编译字节码为源代码.
参数说明如下:
参数名称 | 参数说明 |
---|---|
class-pattern | 类名表达式匹配 |
[E] | 开启正则表达式匹配,默认为通配符匹配 |
示例命令如下:
|
|
mc
Memory Compiler/内存编译器,编译.java文件生成.class
示例命令如下:
|
|
redefine
加载外部的.class文件,推荐使用retransform
示例命令如下:
|
|
redefine的限制如下:
- 不允许新增加field/method
- 正在跑的函数,没有退出不能生效,比如下面新增加的System.out.println,只有run()函数里的会生效
|
|
-
redefine后的原来的类不能恢复,redefine有可能失败(比如增加了新的field)
-
reset命令对redefine的类无效.如果想重置,需要redefine原始的字节码
-
redefine命令和jad/watch/trace/monitor/tt等命令会冲突.执行完redefine之后,如果再执行上面提到的命令,则会把redefine的字节码重置
retransform
加载外部的.class文件
示例命令如下:
|
|
若要消除retransform的影响需进行下述步骤:
- 删除这个类对应的retransform entry
- 重新触发retransform
retransform的限制如下:
- 不允许新增加field/method
- 正在跑的函数,没有退出不能生效,比如下面新增加的System.out.println,只有run()函数里的会生效
|
|
dump
将已加载类的字节码文件保存到特定目录:%HOMEPATH%/logs/arthas/classdump
参数说明如下:
参数名称 | 参数说明 |
---|---|
class-pattern | 类名表达式匹配 |
[c:] | 类所属ClassLoader的hashcode |
[E] | 开启正则表达式匹配,默认为通配符匹配 |
示例命令如下:
|
|
classloader
获取类加载器的信息
参数说明如下:
参数名称 | 参数说明 |
---|---|
[l] | 按类加载实例进行统计 |
[t] | 打印所有ClassLoader的继承树 |
[a] | 列出所有ClassLoader加载的类,请谨慎使用 |
[c:] | ClassLoader的hashcode |
[c: r:] | 用ClassLoader去查找resource |
[c: load:] | 用ClassLoader去加载指定的类 |
示例命令如下:
|
|
进阶命令
命令 | 说明 |
---|---|
monitor | 监控指定类中方法的执行情况 |
watch | 观察到指定方法的调用情况 |
trace | 对方法内部调用路径进行追踪,并输出方法路径上每个节点上耗时 |
stack | 输出当前方法被调用的路径 |
tt | 记录指定方法每次调用的入参和返回信息 |
options | 全局开关 |
monitor
监控指定类中方法的执行情况
参数说明如下:
参数名称 | 参数说明 |
---|---|
class-pattern | 类名表达式匹配 |
method-pattern | 方法名表达式匹配 |
[E] | 开启正则表达式匹配,默认为通配符匹配 |
[c:] | 统计周期,默认值为120秒 |
示例命令如下:
|
|
监控项说明如下:
监控项 | 说明 |
---|---|
timestamp | 时间戳 |
class | Java类 |
method | 方法(构造方法、普通方法) |
total | 调用次数 |
success | 成功次数 |
fail | 失败次数 |
rt | 平均耗时 |
fail-rate | 失败率 |
watch
观察指定方法的调用情况
参数说明如下:
参数名称 | 参数说明 |
---|---|
class-pattern | 类名表达式匹配 |
method-pattern | 方法名表达式匹配 |
express | 观察表达式 |
condition-express | 条件表达式 |
[b] | 在方法调用之前观察before |
[e] | 在方法异常之后观察exception |
[s] | 在方法返回之后观察success |
[f] | 在方法结束之后(正常返回和异常返回)观察finish |
[E] | 开启正则表达式匹配,默认为通配符匹配 |
[x:] | 指定输出结果的属性遍历深度,默认为1 |
- watch 命令定义了4个观察事件点,即-b方法调用前,-e方法异常后,-s 方法返回后,-f方法结束后
- 4个观察事件点-b、-e、-s默认关闭,-f 默认打开,当指定观察点被打开后,在相应事件点会对观察表达式进行求值并输出
- 这里要注意方法入参和方法出参的区别,有可能在中间被修改导致前后不一致,除了-b事件点params代表方法入参外,其余事件都代表方法出参
- 当使用-b时,由于观察事件点是在方法调用前,此时返回值或异常均不存在
示例命令如下:
|
|
|
|
|
|
|
|
trace
对方法内部调用路径进行追踪,并输出方法路径上的每个节点上耗时
参数说明如下:
参数名称 | 参数说明 |
---|---|
class-pattern | 类名表达匹配 |
method-pattern | 方法名表达式匹配 |
condition-express | 条件表达式,使用OGNL表达式 |
[E] | 开启正则表达式匹配,默认是通配符匹配 |
[n:] | 设置命令执行次数 |
#cost | 方法执行耗时,单位是毫秒 |
示例命令如下:
|
|
|
|
|
|
stack
输出当前方法被调用的调用路径
参数说明如下:
参数名称 | 参数说明 |
---|---|
class-pattern | 类名表达式匹配 |
method-pattern | 方法名表达式匹配 |
condition-express | 条件表达式,OGNL |
[E] | 开启正则表达式匹配,默认为通配符匹配 |
[n:] | 执行次数限制 |
示例命令如下:
|
|
|
|
tt
记录下指定方法每次调用的入参和返回信息,并能对这些不同时间下调用的信息进行观测
参数说明如下:
参数名称 | 说明 |
---|---|
-t | 记录某个方法在一个时间段中的调用 |
-l | 显示所有已经记录的列表 |
-n 次数 | 只记录多少次 |
-s 表达式 | 搜索表达式 |
-i 索引号 | 查看指定索引号的详细调用信息 |
-p | 重新调用指定的索引号时间碎片 |
示例命令如下:
|
|
表格字段说明如下:
表格字段 | 字段解释 |
---|---|
INDEX | 时间片段记录编号,每一个编号代表着一次调用,后续tt还有很多命令都是基于此编号指定记录操作,非常重要 |
TIMESTAMP | 方法执行的本机时间,记录了这个时间片段所发生的本机时间 |
COST(ms) | 方法执行的耗时 |
IS-RET | 方法是否以正常返回的形式结束 |
IS-EXP | 方法是否以抛异常的形式结束 |
OBJECT | 执行对象的hashCode(),注意,曾经有人误认为是对象在JVM中的内存地址,但很遗憾他不是.但他能帮助你简单的标记当前执行方法的类实体 |
CLASS | 执行的类名 |
METHOD | 执行的方法名 |
options
全局开关
全局选项如下:
名称 | 默认值 | 描述 |
---|---|---|
unsafe | false | 是否支持对系统级别的类进行增强,打开该开关可能导致把JVM搞挂,请慎重选择! |
dump | false | 是否支持被增强了的类dump到外部文件中,如果打开开关,class文件会被dump到/${application dir}/arthas-class-dump/目录下,具体位置详见控制台输出 |
batch-re-transform | true | 是否支持批量对匹配到的类执行retransform操作 |
json-format | false | 是否支持json化的输出 |
disable-sub-class | false | 是否禁用子类匹配,默认在匹配目标类的时候会默认匹配到其子类,如果想精确匹配,可以关闭此开关 |
debug-for-asm | false | 打印ASM相关的调试信息 |
save-result | false | 是否打开执行结果存日志功能,打开之后所有命令的运行结果都将保存到~/logs/arthas-cache/result.log中 |
job-timeout | 1d | 异步后台任务的默认超时时间,超过这个时间,任务自动停止;比如设置 1d, 2h, 3m, 25s,分别代表天、小时、分、秒 |
print-parent-fields | true | 是否打印在parent class里的filed |
示例命令如下:
|
|