Arthas- 技术专题 - 使用指南
Arthas
是 Alibaba 开源的 Java 诊断工具,采用命令行交互模式,提供了丰富的功能,是排查 jvm 相关问题的利器。
在逛 github 时,发现这款利器,深入了解之后,简直惊为天人。下面先列举一下它能做的一些事情:
提供性能看板,包括线程、cpu、内存等信息,并且会定时的刷新。
根据各种条件查看线程快照。比如找出 cpu 占用率最高的 n 个线程等
输出 jvm 的各种信息,如 gc 算法、jdk 版本、ClassPath 等
查看/设置 sysprop 和 sysenv
查看某个类的静态属性,也可以通过 ognl 语法执行一些语句
查看已加载的类的详细信息,比如这个类从哪个 jar 包加载的。也可以查看类的方法的信息
dump 某个类的字节码到指定目录
直接反编译指定的类
查看类加载器的一些信息
可以让 jvm 重新加载某个类
监控方法的执行,同时可以获取到执行的入参、出参以及抛出的异常
追踪方法执行的调用栈,以及各个方法的调用时间
有一些命令不会介绍的太详细,因为官方文档已经写的很棒了,我没必要再这复述。想深入了解的朋友也可以直接去看 arthas 的官方文档,中文的,很容易阅读。
一.安装和使用 Arthas
官方文档:https://alibaba.github.io/arthas/install-detail.html
安装
直接通过 java -jar 启动:
或者直接下载 arthas 的压缩包,然后解压:
启动 asthas 进程后,它会列出所有的 jvm 进程,并让我们选择要 attach 哪个进程。attach 目标进程后,就进入 athas 的交互命令行了,这时候就可以开始输入 arthas 对应的命令使用了
卸载
二.Arthas 的各个命令
1. dashboard
进入当前系统的实时数据面板,按 ctrl+c 退出。这个面板会实时刷新,其中包括线程信息、内存信息、gc 信息、还有一些运行时的数据。
另外,当运行在 Ali-tomcat 时,会显示当前 tomcat 的实时信息,如 HTTP 请求的 qps, rt, 错误数, 线程池信息等等。
下面是 arthas 上面的一张 demo 图
在这里插入图片描述
2. thread
通过 thread 命令可以查看当前 jvm 进程的线程详情。可以查看线程的 cpu 使用时间占比,通过指定各种参数可以找出最忙的几个线程,以及阻塞其他线程的线程。具体如何使用这里不多做介绍,大家可以去看 arthas 的官方文档。
3. jvm
通过 jvm 命令直接输出当前 jvm 的各种信息。
4. sysprop 和 sysenv
通过 sysprop 可以查看所有的系统变量,也可以设置某个系统变量。同理,通过 sysenv 可以查看所有的操作系统环境变量,也可以查看设置某个环境变量。
5. getstatic
通过该命令可以查看类的静态属性。不过查看类的静态属性 ognl 命令也可以做到,官方也比较推荐使用 ognl 表达式来做。
不过使用 getstatic 可以使用通配符来查看变量,好像用 ognl 不行。(也可能是我对 ognl 表达式了解还不够)
6. ognl
通过 ognl 表达式来执行一些语句。
ognl 表达式在 arthas 中用的还是比较多的,语法也比较简单。在后面的 monitor、watch、trace、stack 等命令中都会排上用场。
关于 ognl,这个 userCase 上有丰富的案例:
https://github.com/alibaba/arthas/issues/11
7. sc 和 sm
通过 sc 可以查看已加载类的相关信息,比如该类是从哪个 jar 包加载的,被哪个类加载器加载的,以及是否是接口等等。
sm 查看已加载类的方法详情。
8. dump
将已加载类的字节码 dump 到本地磁盘上。
9. jad
反编译已加载的类。让它变成可读的形式。
有时我们经常会不确定线上或者测试环境的包是否是我们修改过的,就可以通过 jad 反编译来看下。
10. classloader
将 JVM 中所有的 classloader 的信息统计出来,并可以展示继承树,urls 等。
11. redefine
该命令可以加载外部的.class
文件,然后覆盖 jvm 已加载的类。注意,这个命令不一定都能覆盖成功,如果添加了新的 field,就不会加载成功。
关于 redefine,arthas 的 github 上有个非常经典的 userCase:
https://github.com/alibaba/arthas/issues/263
大体就是作者遇到项目中的日志一直输出[] [] [] No credential found
,想要找到是哪个类输出的。由于大多数日志框架输出日志时都用到了 StringBuilder,因此作者对 StringBuilder 的 toString 方法做了以下修改:
改完类之后再用 redefine 把修改后的 StringBuilder 加载进去,这样,当后面继续输出[] [] [] No credential found
就可以知道到底是从哪里输出的了。
12. monitor
monitor 命令可以监控方法的执行情况。比如调用成功次数,失败次数,失败率、平均执行时间等等。默认 120 秒输出一次,也就是说,当我们输入 monitor 命令之后,每 120 秒就会输出一次统计结果。
通过-c 参数可以修改输出频率,支持通配符和正则表达式。
13. watch
让你能方便的观察到指定方法的调用情况。能观察到的范围为:返回值
、抛出异常
、入参
,通过编写 OGNL 表达式进行对应变量的查看。
watch 的使用姿势比较丰富,可以在四个不同的场景观察方法的执行。比如方法调用之前、方法调用之后、方法异常之后、方法结束之后。默认观察的是方法结束之后。
如果观察的是方法结束之后的场景,由于入参可能在执行方法时被改变,所以此时输出的可能不是真正的入参。因此,要看真正的入参,要看方法调用之前的,也就是加上-b 的参数。
另外,使用-b 参数观察的话,则观察不到方法返回的结果以及抛出的异常了。
相关参数:
在填写条件表达式时要注意一点,条件表达式中的 params 默认都是获取的方法执行完后的参数信息,比如入参 a 的属性 name 方法执行前是"hello" ,
在方法执行后变成了"world",那么条件表达式传入'params[0].name="hello"'
将不会输出,只有填入'params[0].name="hello"'
才可以匹配上。
这点对于后面的 trace、stack 命令也是一样的。
14. trace
方法内部调用路径,并输出方法路径上的每个节点上耗时。但是该命令只能输出一级调用的方法耗时,往下的就不会输出了。比如我定义了一个类 Test
当我要观察Test a
时,trace 命令只会输出b()
的耗时,而不会输出c()
的耗时。因为对方法 a 来说,只有b()
是一级调用。
trace 命令也可以使用条件表达式,来过滤一些不想要的输出
友情提醒下,
trace
在执行的过程中本身是会有一定的性能开销,在统计的报告中并未像 JProfiler 一样预先减去其自身的统计开销。所以这统计出来有些许的不准,渲染路径上调用的类、方法越多,性能偏差越大。但还是能让你看清一些事情的。这里存在一个统计不准确的问题,就是所有方法耗时加起来可能会小于该监测方法的总耗时,这个是由于 Arthas 本身的逻辑会有一定的耗时
15. stack
输出当前方法被调用的调用路径。用法和 trace 差不多
16. tt
tt 命令会记录每次方法调用的各种信息。它和 watch 有些相似但是它能记录下各个时间点的调用信息,之后随时查看,甚至 replay 这次调用。
在这里插入图片描述
从上图中我们可以看到,通过-i
参数我们可以直接查看之前某次调用的详细信息。
replay 某次调用:
使用 tt 进行方法 replay 时,要注意 2 点
17. options
options 用来打开关闭某些功能:
评论 (1 条评论)