Arthas 是阿里中间件基于 Greys 进⾏⼆次开发开源的一个监控线上应用内存、线程、gc情况的诊断产品,能在不修改服务代码的情况下,对我们产生的业务问题进行诊断,例如查看方法的入参、出参、异常或方法调用链的耗时等,能够很好的提升线上问题排查效率。

Arthas 官方文档地址:https://alibaba.github.io/arthas/index.html

在官方文档中已经提到,Arthas 能为你做什么?

  1. 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
  2. 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
  3. 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
  4. 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
  5. 是否有一个全局视角来查看系统的运行状况?
  6. 有什么办法可以监控到JVM的实时运行状态?
  7. 怎么快速定位应用的热点,生成火焰图?

安装

下载arthas-boot.jar,之后使用java -jar启动即可:

1
2
wget https://alibaba.github.io/arthas/arthas-boot.jar
java -jar arthas-boot.jar

启动后选择对应java应用进程即可

命令

dashboard

显示当前系统的实时数据面板,可以按 ctrl+c 退出。

使用参考

数据说明

  • ID: Java线程ID,注意这个ID并不能跟jstack中的nativeID对应
  • NAME: 线程名称
  • GROUP: 线程组名称
  • PRIORITY: 线程优先级, 范围为1~10,越大优先级越高
  • STATE: 线程状态
  • CPU%: 线程消耗的cpu占比,采样100ms,将所有线程在这100ms内的cpu使用量求和,再算出每个线程的cpu使用占比。
  • TIME: 线程运行总时间,数据格式为分:秒
  • INTERRUPTED: 线程当前的中断位状态
  • DAEMON: 是否是daemon线程

thread

查看当前线程信息及堆栈信息

参数说明

参数名称 参数说明 使用范例
id 线程id thread 1
n 指定最忙的前N个线程并打印堆栈 thread -n 5
b 找出当前阻塞其他线程的线程 thread -b
i 指定cpu占比统计的采样间隔,单位为毫秒 thread -n 5 -i 1000

thread 查看所有线程信息

arthas-thread
arthas-thread

thread -n 5 查看当前最忙的前N个线程并打印堆栈信息

arthas-thread-n
arthas-thread-n

这里的cpu统计的是一段采样间隔内,当前JVM里各个线程所占用的cpu时间占总cpu时间的百分比。

其计算方法为: 首先进行一次采样,调用的是java.lang.management.ThreadMXBean#getThreadCpuTime这个接口,获得所有线程的cpu的使用时间,然后睡眠一段时间,默认100ms,可以通过-i参数指定,然后再采样一次,最后得出这段时间内各个线程消耗的cpu时间情况,最后算出百分比。

因为这个统计也会产生一定的开销,因此会看到as的线程占用一定的百分比,为了降低统计自身的开销带来的影响,可以把采样间隔拉长一些,比如5000毫秒。

jad

将JVM中实际运行的class反编译指定已加载类的java源码

参数说明

参数名称 参数说明 使用范例
class-pattern 类名匹配 jad java.lang.String
c 指定类加载器中的类进行编译 jad org.slf4j.Logger -c 55f96302

指定需要反编译的类

1
jad java.lang.String
arthas-jad
arthas-jad

反编译时只显示源码

1
jad --source-only java.lang.String
arthas-jad-only
arthas-jad-only

反编译时指定方法

1
jad java.lang.String equals
arthas-jad-method
arthas-jad-method

反编译时指定类加载器

1
2
jad org.slf4j.Logger
jad org.slf4j.Logger -c 55f96302

当有多个类加载器加载了所指定的类时,jad 命令会输出对应不同类加载器中实例的 hashcode,此时重新执行 jad 命令并使用 -c 参数指定 hashcode 即可指定加载类加载器中的类

arthas-jad-c
arthas-jad-c

watch

watch 命令可以观察方法的返回值、入参、出参及方法抛出异常。

参数说明

参数名称 参数说明
b 方法调用之前观察
e 方法异常之后观察
s 方法返回之后观察
f 方法结束之后(正常返回和异常返回)观察
x 指定输出结果的属性遍历深度,默认为 1

watch 命令示例 : watch demo.MathGame primeFactors “{params,returnObj}” -x 2

  • watch 命令定义了4个观察事件点,即 -b 方法调用前,-e 方法异常后,-s 方法返回后,-f 方法结束后
  • 4个观察事件点 -b-e-s 默认关闭,-f 默认打开,当指定观察点被打开后,在相应事件点会对观察表达式进行求值并输出

条件表达式

1
watch demo.MathGame primeFactors "{params[0],target}" "params[0]<0
  • 限定条件为第一个参数小于0的值

观察方法异常信息

1
watch demo.MathGame primeFactors "{params[0],throwExp}" -e -x 2
  • -x 表示遍历深度,通过调整该参数来打印具体结果,默认值为1
  • -e 表示抛出异常时

根据方法耗时进行过滤

1
watch demo.MathGame primeFactors '{params, returnObj}' '#cost>200' -x 2
  • #cost 的单位为 ms,只输出方法耗时大于200ms的方法调用

观察当前对象中的属性

1
watch demo.MathGame primeFactors 'target.illegalArgumentCount'
  • 使用target来表示当前对象,使用target.fieldName来访问对象中的某属性

trace

方法内部调用路径,并输出方法路径上的每个节点上耗时

1
trace demo.MathGame run -n 1 '#cost > 10'
  • -n 指定方法捕捉结果次数
  • #cost 可以指定方法的执行耗时大于某个指定的时间后的结果

其他命令

  • jvm——查看当前JVM信息

  • sc——查看JVM已加载的类信息

  • sm——查看已加载类的方法信息

  • dump——dump 已加载类的 bytecode 到特定目录

  • headdump——dump java heap, 类似jmap命令heap dump功能

  • classloader——查看classloader的继承树,urls,类加载信息

  • monitor——方法执行监控

    1
    monitor -c 5 demo.MathGame primeFactors
  • stack——输出当前方法被调用的调用路径

    1
    stack demo.MathGame primeFactors 'params[0]<0' '#cost>5'

基础命令

  • help——查看命令帮助信息
  • cls——清空当前屏幕区域
  • session——查看当前会话的信息
  • reset——重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类
  • version——输出当前目标 Java 进程所加载的 Arthas 版本号
  • history——打印命令历史
  • quit——退出当前 Arthas 客户端,其他 Arthas 客户端不受影响
  • stop——和shutdown命令一致(推荐使用,避免误操作)
  • shutdown——关闭 Arthas 服务端,所有 Arthas 客户端全部退出
  • keymap——Arthas快捷键列表及自定义快捷键