文章目录
Arthas 在线学习网站
1. Arthas 安装与启动
Authas 是一款开源的 Java 诊断工具。
我使用的系统是 window。
下载命令:curl -O https://alibaba.github.io/arthas/arthas-boot.jar
(可以直接把连接复制到迅雷,下载很快)
使用 Arthas 之前需要保证得有 Java 程序在运行
启动 Arthas,命令:java -jar E:\VMShare\Arthas\arthas-boot.jar
选择其中一个 Java 进程,这里我选 3,也就是 SystemApplication(这是我项目中的一个 SpringBoot 启动类)
到这里就登陆成功,可以使用 Arthas 了。
2. Arthas 参数的使用
1. help
help:查看可以使用的命令和各个命令的描述。
Arthas 里每一个命令都有详细的帮助信息。可以用 -h 来查看。帮助信息里有 EXAMPLES 和 WIKI 链接。如:sysprop -h
2. 一些基本命令
- cls:清屏命令,相当于我们平时 Linux 中使用的 clear,window 系统的清屏命令也是 cls。
- pwd:返回当前的工作目录,和linux命令类似。
- cat:打印文件内容,和 Linux 里的 cat 命令类似,因为工作目录是
D:\IDEA_CODE\ihrm_parent
,所以这里直接cat pom.xml
,也就是打印D:\IDEA_CODE\ihrm_parent\pom.xml
的内容。
- session:查看当前会话的信息。
- reset:重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类。
- version:输出当前目标 Java 进程所加载的 Arthas 版本号。
- quit、exit:退出当前 Arthas 客户端,其他 Arthas 客户端不受影响。
- stop:关闭 Arthas 服务端,所有 Arthas 客户端全部退出。
3. history
history:可以查看自己之前使用过的命令
还可以使用管道来过滤,如:history | grep sys
4. dashboard
dashboard:查看当前系统的实时数据面板,会显示出线程 (按照 CPU 占用百分比倒排)、内存(堆空间实时情况)、GC 情况等数据,输入 Q 或者 Ctrl+C
可以退出 dashboard 命令。
常用的参数:
- -i:每次执行间隔时间,如:
dashboard -i 1000
- -n:执行多少次 dashboard,不指定的话会一直刷新,如:
dashboard -n 2
5. thread
thread:查看当前 JVM 中的线程信息的。
thread 后可以加上线程 ID,表示打印线程 ID 为 n 的线程的堆栈信息,Arthas 支持管道,可以用 thread n | grep 'main('
查找到 main class。
常用参数:
- -b:查看目前 block 的线程,如:
thread -b
- -i:查看在接下来的多长时间内统计 CPU 利用率,如:
thread -i 1000
- -n:查看 CPU 占用率前几的线程的堆栈信息,如:
thread -n 2
6. sc
即 Search class
sc:查找所有 JVM 里已加载的类,如果搜索的是接口,还会搜索所有的实现类,sc 还支持通配符 *
通过 -d 参数,可以打印出类加载的具体信息,很方便查找类加载问题,如:sc -d *UserController
通过 sc -h
可以查看更多命令
7. sm
即 search method
sm:查找对应类的所有方法。
- 查找类的具体函数。比如:
sm com.ihrm.system.controller.UserController
- 通过 -d 参数可以打印函数的具体属性:
sm -d com.ihrm.system.controller.UserController
- 也可以查找特定的函数,比如查找构造函数:
sm -d com.ihrm.system.controller.UserController <init>
8. jad
jad:反编译代码,查找类的具体函数。如:jad com.ihrm.system.controller.UserController
通过--source-only
参数可以只打印出在反编译的源代码:jad --source-only com.ihrm.system.controller.UserController
9. watch
watch:查看函数的参数/返回值/异常信息,第一个参数是类名,支持通配,第二个参数是函数名,支持通配,如:watch com.ihrm.system.controller.UserController login params
,当我在自己项目的登录页面点击登录时 (也就是相应的 login 方法被调用时),arthas 界面打印出下面的数据,输入 Q 或者 Ctrl+C
可以退出 watch 命令
- 第三个参数是返回值表达式,它实际上是一个 ognl 表达式,它支持一些内置对象:
- loader:本次调用类所在的 ClassLoader
- clazz:本次调用类的 Class 引用
- method:本次调用方法反射引用
- target:本次调用类的实例
- params:本次调用参数列表,这是一个数组,如果方法是无参方法则为空数组
- returnObj:本次调用返回的对象。当且仅当 isReturn==true 成立时候有效,表明方法调用是以正常返回的方式结束。如果当前方法无返回值 void,则值为 null
- throwExp:本次调用抛出的异常。当且仅当 isThrow==true 成立时有效,表明方法调用是以抛出异常的方式结束
- isBefore:辅助判断标记,当前的通知节点有可能是在方法一开始就通知,此时 isBefore==true 成立,同时
isThrow==false 和 isReturn==false
,因为在方法刚开始时,还无法确定方法调用将会如何结束 - isThrow:辅助判断标记,当前的方法调用以抛异常的形式结束
- isReturn:辅助判断标记,当前的方法调用以正常返回的形式结束。
- 你可以利用这些内置对象来组成不同的表达式。比如返回一个数组:
watch com.ihrm.system.controller.UserController * '{params[0], target, returnObj}'
,点击我的项目界面上的登录按钮
- 条件表达式:watch 命令支持在第 4 个参数里写条件表达式,比如:
watch com.example.demo.arthas.user.UserController * returnObj 'params[0] > 100'
- 当异常捕获时,watch 命令支持 -e 选项,表示只捕获抛出异常时的请求:
watch com.example.demo.arthas.user.UserController * "{params[0],throwExp}" -e
- 按照耗时进行过滤:watch 命令支持按请求耗时进行过滤,比如:
watch com.example.demo.arthas.user.UserController * '{params, returnObj}' '#cost>200'
10.Tab 键
Tab 键:自动补全,很多地方都能用。
11. sysprop
sysprop:打印所有的 System Properties 信息
- 也可以指定单个 key:
sysprop java.vendor
- 也可以通过 grep 来过滤:
sysprop | grep vendor
- 也可以设置新的 value:
sysprop testKey testValue
12. sysenv
sysenv:获取到环境变量。和 sysprop 命令的用法类似。
13. jvm
jvm:打印出 JVM 的各种详细信息。
14. keymap
Arthas 支持常见的命令行快捷键,比如Ctrl + A
跳转行首,Ctrl + E
跳转行尾。更多的快捷键可以用 keymap 命令查看。
keymap:Arthas 快捷键列表及自定义快捷键
15. 支持管道
Arthas 支持在 pipeline 之后,执行一些简单的命令,比如:sysprop | grep java
、sysprop | wc -l
。
16. ognl
ognl:在 Arthas 里,有一个单独的 ognl 命令,可以动态执行代码。
- 调用 static 函数,如:
ognl '@java.lang.System@out.println("hello ognl")'
,可以检查控制台里的进程输出,发现打印出了 hello ognl。
- 获取类中的静态字段,如:获取 UserController 类里的 i 字段:
ognl @com.ihrm.system.controller.UserController@i
- 还可以通过 -x 参数控制返回值的展开层数。比如:
ognl -c 1be6f5c3 -x 2 @com.ihrm.system.controller.UserController@i
- 通过 -c 参数指定类加载器,后面跟 类加载器的 哈希码
- 执行多个表达式,赋值给临时变量,返回一个 List,
ognl '#value1=@System@getProperty("java.home"), #value2=@System@getProperty("java.runtime.name"), {#value1, #value2}'
- 在 Arthas 里 ognl 表达式是很重要的功能,在很多命令里都可以使用 ognl 表达式。OGNL特殊用法请参考、OGNL表达式官方指南
17. monitor
monitor:是一个非实时返回命令,实时返回命令是输入之后立即返回,而非实时返回的命令,则是不断的等待目标 Java 进程返回信息,直到用户输入 Ctrl+C 或者 Q 为止。
服务端是以任务的形式在后台跑任务,植入的代码随着任务的中止而不会被执行,所以任务关闭后,不会对原有性能产生太大影响,而且原则上,任何Arthas命令不会引起原有业务逻辑的改变。
监控的维度说明:
18. classloader
查看 classloader 的继承树,urls,类加载信息。
参数:
- -t :把 classloader 的树打印出来,也会打印出来粗略的 hashcode
- -l :根据 classloader 实例的个数来打印 classloader,会打印出来 hashcode,如:
classloader -l
- -c :用 classloader 对应的 hashcode 来查看对应的 jar urls,如:
classloader -c 123772c4
- 也可以尝试查找类的class文件:
classloader -c 123772c4 -r java/lang/String.class
- 使用 classloader 去加载类,如:
classloader -c 123772c4 --load demo.MathGame
19. trace
trace:方法内部调用路径,并输出方法路径上的每个节点上耗时。
平时主要使用 -j (忽略 jdk method trace)、’#cost>10’(过滤耗时时间) -n (执行次数):
20. stack
stack:输出当前方法被调用的调用路径,很多时候我们都知道一个方法被执行,但这个方法被执行的路径非常多,或者你根本就不知道这个方法是从那里被执行了,此时你需要的是 stack 命令。
主要使用 -n 命令,用于控制执行次数:
21. tt
字段说明:
- INDEX:时间片段记录编号,每一个编号代表着一次调用,后续tt还有很多命令都是基于此编号指定记录操作,非常重要。
- TIMESTAMP:方法执行的本地时间,记录了这个时间片段所发生的本地时间。
- COST(ms):方法执行的耗时
- IS-RET:方法是否以正常返回的形式结束
- IS-EXP:方法是否以抛异常的形式结束
- OBJECT:执行对象的 hashCode(),注意,曾经有人误认为是对象在 JVM 中的内存地址,但很遗憾他不是。但他能帮助你简单的标记当前执行方法的类实体
- CLASS:执行的类名
- METHOD:执行的方法名
注意:
- tt 命令有很多个主参数,-t 就是其中之一。这个参数的表明希望记录下例如类 *Test 的 print 方法的每次执行情况。
- 当你执行一个调用量不高的方法时可能你还能有足够的时间用 CTRL+C 中断 tt 命令记录的过程,但如果遇到调用量非常大的方法,瞬间就能将你的 JVM 内存撑爆。此时你可以通过 -n 参数指定你需要记录的次数,当达到记录次数时 Arthas 会主动中断 tt 命令的记录过程,避免人工操作无法停止的情况。
- 当你用 tt 记录了一大片的时间片段之后,你希望能从中筛选出自己需要的时间片段,这个时候你就需要对现有记录进行检索。你需要一个 -s 参数。同样的,搜索表达式的核心对象依旧是 Advice 对象。
- 对于具体一个时间片的信息而言,你可以通过 -i 参数后边跟着对应的 INDEX 编号查看到他的详细信息。
- 当你稍稍做了一些调整之后,你可能需要前端系统重新触发一次你的调用,此时需要前端配合联调的同学再次发起一次调用。而有些场景下,这个调用不是这么好触发的。tt 命令由于保存了当时调用的所有现场信息,所以我们可以自己主动对一个 INDEX 编号的时间片自主发起一次调用,从而解放你的沟通成本。此时你需要 -p 参数。通过 --replay-times 指定调用次数,通过 --replay-interval 指定多次调用间隔(单位ms, 默认1000ms)
你会发现结果虽然一样,但调用的路径发生了变化,有原来的程序发起变成了 Arthas 自己的内部线程发起的调用了。