Arthas使用实践

一、官方文档

开源地址:https://github.com/alibaba/arthas
官方文档:https://alibaba.github.io/arthas

二、命令介绍

1. Dashboard 实时数据
[i:]刷新实时数据的时间间隔 (ms),默认5000ms
[n:]刷新实时数据的次数
2. Thread 查看当前线程信息,查看线程的堆栈
id  线程id
[n:]  指定最忙的前N个线程并打印堆栈
[b]  找出当前阻塞其他线程的线程
[i <value>]  指定cpu占比统计的采样间隔,单位为毫秒
3. Jad  反编译指定已加载类的源码
class-pattern  类名表达式匹配
[c:]  类所属 ClassLoader 的 hashcode
[E]  开启正则表达式匹配,默认为通配符匹配
4. Jvm
THREAD相关
COUNT: JVM当前活跃的线程数
DAEMON-COUNT: JVM当前活跃的守护线程数
PEAK-COUNT: 从JVM启动开始曾经活着的最大线程数
STARTED-COUNT: 从JVM启动开始总共启动过的线程次数
DEADLOCK-COUNT: JVM当前死锁的线程数
文件描述符相关
MAX-FILE-DESCRIPTOR-COUNT:JVM进程最大可以打开的文件描述符数
OPEN-FILE-DESCRIPTOR-COUNT:JVM当前打开的文件描述符数
5. Classloader
[l]  按类加载实例进行统计
[t]  打印所有ClassLoader的继承树
[a]  列出所有ClassLoader加载的类,请谨慎使用
[c:]  ClassLoader的hashcode
[classLoaderClass:]  指定执行表达式的 ClassLoader 的 class name
[c: r:]  用ClassLoader去查找resource
[c: load:]  用ClassLoader去加载指定的类
6. Logger
logger --name ROOT --level debug 修改日志级别
logger -n org.springframework.web 查看指定名字的logger信息
logger -c 2a139a55 查看指定classloader的logger信息
7. Sysprop 查看当前JVM的系统属性
Sysprop 查看所有
Sysprop <property-name>  <property-value> 修改单个
8. Sysenv 查看当前JVM的环境属性
Sysenv 查看所有
Sysenv <env-name> 查看单个
9. Vmoption 查看,更新VM诊断相关的参数
vmoption [name] [value] 更新
10.Perfcount 查看当前JVM的 Perf Counter性能统计信息
11. Mbean 便捷的查看或监控 Mbean 的属性信息
MBean其实也是JavaBean的一种,但是MBean往往代表的是JMX中的一种可以被管理的资源。
MXBean与MBean的区别主要是在于在接口中会引用到一些其他类型的类时,其表现方式的不一样。在MXBean中,如果一个MXBean的接口定义了一个属性是一个自定义类型,如MemoryMXBean中定义了heapMemoryUsage属性,这个属性是MemoryUsage类型的,当JMX使用这个MXBean时,这个MemoryUsage就会被转换成一种标准的类型,这些类型被称为开放类型,是定义在javax.management.openmbean包中的。而这个转换的规则是,如果是原生类型,如int或者是String,则不会有变化,但如果是其他自定义类型,则被转换成CompositeDataSupport类。
MBean, MXBean接口后缀,被实现类去掉后缀。
12. Ognl
express  执行的表达式
[c:]  执行表达式的 ClassLoader 的 hashcode,默认值是SystemClassLoader
[classLoaderClass:]  指定执行表达式的 ClassLoader 的 class name
[x]  结果对象的展开层次,默认值1
查看静态变量,可调用静态方法 ognl '@com.shunwang.buss.agent.client.config.AgentApiConfig@APPLICATION_NAME‘
执行多行表达式,赋值给临时变量,返回一个List:
ognl '#value1=@System@getProperty("java.home"), #value2=@System@getProperty("java.runtime.name"), {#value1, #value2}'
13. Sc 查看JVM已加载的类信息
参数名称    参数说明
class-pattern    类名表达式匹配
method-pattern    方法名表达式匹配
[d]    输出当前类的详细信息,包括这个类所加载的原始文件来源、类的声明、加载的ClassLoader等详细信息。
如果一个类被多个ClassLoader所加载,则会出现多次
[E]    开启正则表达式匹配,默认为通配符匹配
[f]    输出当前类的成员变量信息(需要配合参数-d一起使用)
[x:]    指定输出静态变量时属性的遍历深度,默认为 0,即直接使用 toString 输出
[c:]    指定class的 ClassLoader 的 hashcode
[classLoaderClass:]    指定执行表达式的 ClassLoader 的 class name
[n:]    具有详细信息的匹配类的最大数量(默认为100)
14. Sm 查看已加载类的方法信息
class-pattern    类名表达式匹配
method-pattern    方法名表达式匹配
[d]    展示每个方法的详细信息
[E]    开启正则表达式匹配,默认为通配符匹配
[c:]    指定class的 ClassLoader 的 hashcode
[classLoaderClass:]    指定执行表达式的 ClassLoader 的 class name
[n:]    具有详细信息的匹配类的最大数量(默认为100)
15. dump 已加载类的 bytecode 到特定目录
16. Heapdump  类似jmap命令的heap dump功能
heapdump --live /tmp/dump.hprof  只dump live对象
17. tt 方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测
-t 记录下来每次执行情况
-n 指定记录的次数
TIMESTAMP 方法执行的本机时间,记录了这个时间片段所发生的本机时间
IS-RET 方法是否以正常返回的形式结束
IS-EXP 方法是否以抛异常的形式结束
OBJECT 执行对象的hashCode()
解决方法重载: 
tt -t *Test print params.length==1
tt -t *Test print 'params[1] instanceof Integer'
解决指定参数: tt -t *Test print params[0].mobile=="13989838402"
构成条件表达式的 Advice 对象: https://arthas.aliyun.com/doc/advice-class.html
tt -l 检索调用记录
tt -s 'method.name=="primeFactors"'
-i [index] 查看详细信息
tt -i 1004 -p 重做一次调用(threadlocal信息会丢失,引用对象入参可能会变更)
18. stack 输出当前方法被调用的调用路径
class-pattern    类名表达式匹配
method-pattern    方法名表达式匹配
condition-express    条件表达式
[E]    开启正则表达式匹配,默认为通配符匹配
[n:]    执行次数限制
例子: stack demo.Test test 'params[0]<0' -n 2
执行时间过滤:'#cost>5'
19. trace 方法内部调用路径,并输出方法路径上的每个节点上耗时
class-pattern    类名表达式匹配
method-pattern    方法名表达式匹配
condition-express    条件表达式
[E]    开启正则表达式匹配,默认为通配符匹配
[n:]    命令执行次数
#cost    方法执行耗时
深入子函数:
a.新开终端telnet localhost 3658 
b.trace demo.MathGame primeFactors --listenerId 3
20. monitor 方法实时监控
monitor -c 5 demo.Test test
21. watch 方法执行数据观测
class-pattern    类名表达式匹配
method-pattern    方法名表达式匹配
express    观察表达式
condition-express    条件表达式
[b]    在方法调用之前观察
[e]    在方法异常之后观察
[s]    在方法返回之后观察
[f]    在方法结束之后(正常返回和异常返回)观察
[E]    开启正则表达式匹配,默认为通配符匹配
[x:]    指定输出结果的属性遍历深度,默认为 1
观察出参:watch demo.Test test "{params,returnObj}" -x 2
入参: -b
条件表达式:watch demo.Test test "{params[0],target}" "params[0]<0"
异常: "{params[0],throwExp}" -e
22. profiler 不断采样生成火焰图
23.支持基本命令:cat,echo,grep,pwd
24. tee 类似传统的tee命令, 用于读取标准输入的数据,并将其内容输出成文件。
  sysprop | tee /path/to/logfile | grep java
  sysprop | tee -a /path/to/logfile | grep java
25. options 全局开关
26. 基础命令
reset——重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类
history——打印命令历史
quit——退出当前 Arthas 客户端,其他 Arthas 客户端不受影响
stop——关闭 Arthas 服务端,所有 Arthas 客户端全部退出
27. mc Memory Compiler/内存编译器,编译.java文件生成.class。
-c 指定classloader
-d 指定输出目录
28. redefine  加载外部的.class文件,redefine jvm已加载的类。
注意, redefine后的原来的类不能恢复.不允许新增加field/method,正在跑的函数,没有退出不能生效.
reset命令对redefine的类无效。如果想重置,需要redefine原始的字节码
redefine命令和jad/watch/trace/monitor/tt等命令会冲突。执行完redefine之后,如果再执行上面提到的命令,则会把redefine的字节码重置。

 

三、如何开始
  1. 下载启动:
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar

  2. 远程连接:arthas tunnel server

wget https://github.com/alibaba/arthas/releases/download/arthas-all-3.3.9/arthas-tunnel-server-3.3.9.jar
java -jar  arthas-tunnel-server.jar
默认情况下,arthas tunnel server的web端口是8080,arthas agent连接的端口是7777。
通过Spring Boot的Endpoint,可以查看到具体的连接信息: http://localhost:8080/actuator/arthas
    • 启动arthas时连接到tunnel server
as.sh --tunnel-server 'ws://192.168.42.157:7777/ws'
    • springboot应用
依赖:
启动监听自身:
<dependency>
    <groupId>com.taobao.arthas</groupId>
    <artifactId>arthas-spring-boot-starter</artifactId>
    <version>3.3.9</version>
</dependency>
 
配置:连接到tunnel server
arthas.agent-id=sadsadsada
arthas.tunnel-server=ws://192.168.42.157:7777/ws
 
四、实践
  1. 实时代码更新:
jad --source-only demo.Test > /tmp/Test.java
修改Test.java
sc -d *Test | grep classLoaderHash 查看类加载hash
mc -c [hash值] /tmp/Test.java -d /tmp 编译
redefine /tmp/demo/Test.class  生效
  2. 修改属性值:
  3. 修改日志属性:
ognl --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader '@com.example.demo.arthas.user.UserController@logger.setLevel(@ch.qos.logback.classic.Level@DEBUG)'
  4. 追踪排查问题:
trace javax.servlet.Filter *  追踪所有Filter函数
trace javax.servlet.Servlet * > /tmp/servlet.txt
 
401:
Access is denied
throw:
  5. 查看5秒内的CPU使用率top n线程栈
thread -n 3 -i 5000
查找线程是否有阻塞
thread -b

 

转载请注明地址:http://www.cnblogs.com/handsomecui/

posted @ 2020-09-24 14:05  handsomecui  阅读(1626)  评论(0编辑  收藏  举报