arthas 简要指令说明

arthas

一款alibaba开源的java 在线分析工具,一般用于分析生产环境的各种故障,或者分析各种性能指标。

下载运行

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

查看整体情况

包括内存,jvm,gc,线程等内容

dashboard

查看线程情况

命令 作用
thread 查看最近20个线程
thread 查看某个线程的堆栈
thread --all 打印全部线程信息
thread -n 3 查看cpu使用率 top 3 线程
thread -b 查看阻塞线程
thread -n 3 -i 5000 查看5s内 cpu top3 线程

执行Spring 命令

用于获取一个bean,调用某个方法,获取某个bean的成员变量的值,修改bean成员变量的值等等

方案1

1.先获取applicationContext对象 执行如下代码后,随意走一个接口

tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod

2.获取context对象后 ,直接getBean获取任意Bean对象,然后执行操作

tt -i 1000 -w 'target.getApplicationContext().getBean("dataSource").dataSourceMap.clear()'

方案2

vmtool --action getInstances --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader --className org.springframework.context.ApplicationContext --express 'instances[0].getBeanDefinitionNames()'

反编译查看源码

查看线上实际运行的代码

jad package_name.class_name

watch监控方法调用情况

查看指定方法每次调用的输入输出参数,抛出的异常信息

参数名称 参数说明
class-pattern 类名表达式匹配
method-pattern 函数名表达式匹配
express 观察表达式,默认值:{params, target, returnObj}
condition-express 条件表达式
[b] 函数调用之前观察
[e] 函数异常之后观察
[s] 函数返回之后观察
[f] 函数结束之后(正常返回和异常返回)观察
[E] 开启正则表达式匹配,默认为通配符匹配
[x:] 指定输出结果的属性遍历深度,默认为 1,最大值是 4
[m ] 指定 Class 最大匹配数量,默认值为 50。长格式为[maxMatch ]。
watch 参数规则 watch 包名 方法名 '{查询对象}' '条件' 选项
查看第一个入参(List)的第一个元素 且只监控一次 watch Test test params[0].get(0) -n 1
参数过滤 watch Test test "params[0].{? #this.age > 5}.{name}" -n 1
复杂操作 watch Test test '(#test=params[0].{name}, #test.add("abc"), #test)' -n 1
声明变量 watch Test test '(#test=new java.util.ArrayList(), #test.add("abc"), #test)' -n
数组塞选 watch Test test '@Test@n.entrySet().iterator.{? #this.key.name() == "RUN"}' -n 1
静态变量 watch Test test '@a.b@c' -n 1
Map中的值 watch Test test '@Test@n.keys' -n 1
打印异常 -e 表示异常事打印 -x表示打印对象的层级 watch cn.bobmao.pro.runtime.common.util.JavaMailUtil sendEmail "throwExp" -e -x 2
查询对象 说明
loader 本次调用类所在的 ClassLoader
clazz 本次调用类的 Class 引用
method 本次调用方法反射引用
target 本次调用类的实例
params 本次调用参数列表,这是一个数组,如果方法是无参方法则为空数组
returnObj 本次调用返回的对象。
throwExp 本次调用抛出的异常

查询静态变量 getstatic

getstatic 命令可以方便的查看类的静态属性

# 直接查看静态变量的值
getstatic class_name field_name
# 直接操作静态变量
getstatic com.alibaba.arthas.Test m 'entrySet().iterator.{? #this.key=="a"}'

指定classloader

有时候需要指定classloader才能访问类,因为这个类不是用默认的classloader加载的或者存在多个classloader。此时需要你先获取classloader

然后在getstatic中使用-c参数传入 classloader的hash值

getstatic -c classLoaderHash demo.MathGame random

查看进程内的所有classloader和层次关系

classloader -t

spring的classloader

org.springframework.boot.loader.LaunchedURLClassLoader

获取spring classloader的hashcode (随便找一个spring bean的类)

classloader -l cn.bobmao.pro.application.controller.ApplicationController

dumpheap

说明 操作
dump到指定目录 heapdump /tmp/dump.hprof
只 dump live 对象 heapdump --live /tmp/dump.hprof

查看jvm统计

查看java进程的启动事件,jdk版本,加载的jar包,已加载类的数量等信息
jvm

参数名 参数说明
COUNT JVM 当前活跃的线程数
DAEMON-COUNT JVM 当前活跃的守护线程数
PEAK-COUNT 从 JVM 启动开始曾经活着的最大线程数
STARTED-COUNT 从 JVM 启动开始总共启动过的线程次数
DEADLOCK-COUNT JVM 当前死锁的线程数
MAX-FILE-DESCRIPTOR-COUNT JVM 进程最大可以打开的文件描述符数
OPEN-FILE-DESCRIPTOR-COUNT JVM 当前打开的文件描述符数

Logger

查看logger日志和修改level等级,比如生产的日志写了一句log.debug 但默认日志等级是info,导致相关日志没有打印,使用本命令可以不重启即可修改等级。

命令 作用
logger 查看当前logger配置
logger -n logger_name 查看具体logger的配置
logger --name ROOT --level debug 修改日志等级 ROOT是logger的name

ognl表达式

阿尔萨斯的很多命令的参数都是支持ognl表达式,比如watch的打印内容 getstatic的执行命令
它允许直接执行指定的java代码,当然ognl本身也是个命令,允许用户单独执行

$ ognl '#value1=@System@getProperty("java.home"), #value2=@System@getProperty("java.runtime.name"), {#value1, #value2}'
@ArrayList[
    @String[/opt/java/8.0.181-zulu/jre],
    @String[OpenJDK Runtime Environment],
]
$ classloader -t
+-BootstrapClassLoader
+-jdk.internal.loader.ClassLoaders$PlatformClassLoader@301ec38b
  +-com.taobao.arthas.agent.ArthasClassloader@472067c7
  +-jdk.internal.loader.ClassLoaders$AppClassLoader@4b85612c
    +-org.springframework.boot.loader.LaunchedURLClassLoader@7f9a81e8

$ ognl -c 7f9a81e8 @org.springframework.boot.SpringApplication@logger
@Slf4jLocationAwareLog[
    FQCN=@String[org.apache.commons.logging.LogAdapter$Slf4jLocationAwareLog],
    name=@String[org.springframework.boot.SpringApplication],
    logger=@Logger[Logger[org.springframework.boot.SpringApplication]],
]
$

退出调试

操作 命令
关闭本次连结 quit exit
关闭调试 stop

reset

还原所有的增强类 清除所有更改

trace

打印方法内部调用路径,并输出方法路径上的每个节点上耗时
用于分析接口调用慢,方法是否被调用了等情况。

参数名称 参数说明
class-pattern 类名表达式匹配
method-pattern 方法名表达式匹配
condition-express 条件表达式
[E] 开启正则表达式匹配,默认为通配符匹配
[n:] 命令执行次数
#cost 方法执行耗时
$ trace demo.MathGame run '#cost > 10'
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 41 ms.
`---ts=2018-12-04 01:12:02;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69
    `---[12.033735ms] demo.MathGame:run()
        +---[0.006783ms] java.util.Random:nextInt()
        +---[11.852594ms] demo.MathGame:primeFactors()
        `---[0.05447ms] demo.MathGame:print()

stack

当方法被执行时,输出当前方法被调用的调用路径

参数名称 参数说明
class-pattern 类名表达式匹配
method-pattern 方法名表达式匹配
condition-express 条件表达式
[E] 开启正则表达式匹配,默认为通配符匹配
[n:] 执行次数限制
[m ] 指定 Class 最大匹配数量,默认值为 50。 实际指class分析层数
stack demo.MathGame primeFactors -m 2
stack demo.MathGame primeFactors 'params[0]<0' -n 2
stack demo.MathGame primeFactors '#cost>5'
$ stack demo.MathGame primeFactors -m 1
Press Q or Ctrl+C to abort.
Affect(class count:1 , method count:1) cost in 561 ms, listenerId: 5.
ts=2022-12-25 21:07:07;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@b4aac2
    @demo.MathGame.primeFactors()
        at demo.MathGame.run(MathGame.java:46)
        at demo.MathGame.main(MathGame.java:38)

vmtool

vmtool 利用JVMTI接口,实现查询内存对象,强制 GC 等功能。

获取对象实例信息

$ vmtool --action getInstances --className java.lang.String --limit 10
@String[][
    @String[com/taobao/arthas/core/shell/session/Session],
    @String[com.taobao.arthas.core.shell.session.Session],
    @String[com/taobao/arthas/core/shell/session/Session],
    @String[com/taobao/arthas/core/shell/session/Session],
    @String[com/taobao/arthas/core/shell/session/Session.class],
    @String[com/taobao/arthas/core/shell/session/Session.class],
    @String[com/taobao/arthas/core/shell/session/Session.class],
    @String[com/],
    @String[java/util/concurrent/ConcurrentHashMap$ValueIterator],
    @String[java/util/concurrent/locks/LockSupport],
]

指定 classloader hash

vmtool --action getInstances --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader --className org.springframework.context.ApplicationContext

通过vmtool拿到 applicationContext对象

vmtool --action getInstances --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader --className org.springframework.context.ApplicationContext --express 'instances[0].getBeanDefinitionNames()'

强制 GC

vmtool --action forceGc

interrupt 指定线程(设置该线程的中断标志为true)

vmtool --action interruptThread -t 1

profiler火焰图

Only support Linux/Mac.
profiler 命令支持生成应用热点的火焰图。本质上是通过不断的采样,然后把收集到的采样结果生成火焰图。

参数名称 参数说明
action 要执行的操作
actionArg 属性名模式
[i:] 采样间隔(单位:ns)(默认值:10'000'000,即 10 ms)
[f:] 将输出转储到指定路径
[d:] 运行评测指定秒
[e:] 要跟踪哪个事件(cpu, alloc, lock, cache-misses 等),默认是 cpu

启动

$ profiler start
Started [cpu] profiling

获取采样树

$ profiler getSamples
23

查看状态

$ profiler status
[cpu] profiling is running for 4 seconds

停止并生成文档

$ profiler stop --format html
profiler output file: /tmp/test/arthas-output/20211207-111550.html
OK

用户案例

https://github.com/alibaba/arthas/issues?q=label%3Auser-case