Alibaba Arthas(阿尔萨斯)诊断工具实战

启动 Arthas 服务

# 方式1: 下载 arthas jar
https://alibaba.github.io/arthas/arthas-boot.jar
# 方式2: 下载 arthas 压缩包, 解压到指定目录, 如: /home/arthas/
https://github.com/alibaba/arthas/releases/download/arthas-all-3.1.4/arthas-3.1.4-bin.zip

# 启动 arthas
λ java -jar arthas-boot.jar
[INFO] arthas-boot version: 3.1.4
[INFO] Process 1240 already using port 3658
[INFO] Process 1240 already using port 8563
[INFO] Found existing java process, please choose one and hit RETURN.
* [1]: 1240 com.answer.ai.Application
  [2]: 3232
  [3]: 23064 org.jetbrains.jps.cmdline.Launcher
1

# 通过 web console 浏览器访问
http://127.0.0.1:8563/

# 退出arthas
# 如果只是退出当前的连接,可以用quit或者exit命令。Attach到目标进程上的arthas还会继续运行,端口会保持开放,下次连接时可以直接连接上。
quit
exit
# 如果想完全退出arthas,可以执行stop命令。
stop

Arthas_3.1.4下载链接

 

命令列表

dashboard

当前系统的实时数据面板

# 当前进程的信息 
dashboard

# 执行 10 次
dashboard -n 10

# 每隔 2000ms 执行一次, 默认: 5000ms
dashboard -i 2000

thread

查看当前线程信息,查看线程的堆栈

# 显示所有线程的信息
thread

# 当前最忙的前N个线程并打印堆栈
thread -n 3

# 显示指定线程的运行堆栈
thread <id>

# 找出当前阻塞其他线程的线程(目前只支持找出synchronized关键字阻塞住的线程, 如果是java.util.concurrent.Lock, 目前还不支持)
thread -b

# 指定采样时间间隔
thread -n 3 -i 1000

jad

反编译指定已加载类的源码

# 反编译指定类
jad com.answer.ai.config.XloProperties

# 反编绎时只显示源代码
jad --source-only com.answer.ai.config.XloProperties

# 反编译指定函数
jad com.answer.ai.config.XloProperties setIeso

# 将反编译代码重定向到文件
jad --source-only com.answer.ai.config.XloProperties > ./Ai.java

sc

查看JVM已加载的类信息

# 查看 com.answer.* 包下已加载的类信息
sc com.answer.*

# -d: 输出当前类的详细信息,包括这个类所加载的原始文件来源、类的声明、加载的ClassLoader等详细信息。如果一个类被多个ClassLoader所加载,则会出现多次
sc -d com.answer.ai.util.XloUtil

# -f: 输出当前类的成员变量信息(需要配合参数-d一起使用)
sc -d -f com.answer.ai.util.XloUtil

sm

查看已加载类的方法信息
sm(Search-Method) 命令只能看到由当前类所声明 (declaring) 的方法,父类则无法看到。

# 查看 XloUtil 类中所有方法信息
sm com.answer.ai.util.XloUtil
# 查看 XloUtil 类中以 un 开头的方法信息
sm com.answer.ai.util.XloUtil un*
# 查看 XloUtil 类中 unzip 方法信息
sm com.answer.ai.util.XloUtil unzip

# -d: 展示每个方法的详细信息
sm -d com.answer.ai.util.XloUtil
sm -d com.answer.ai.util.XloUtil un*
sm -d com.answer.ai.util.XloUtil unzip

watch

方法执行数据观测。 让你能方便的观察到指定方法的调用情况。能观察到的范围为:返回值抛出异常入参,通过编写 OGNL 表达式进行对应变量的查看。

watch 命令定义了4个观察事件点, 即: -b 方法调用前, -e 方法异常后, -s 方法返回后, -f 方法结束后(默认打开)

# 观察方法出参和返回值. -x: 指定输出结果的属性遍历深度, 默认为 1
watch com.answer.ai.controller.OcrController asyncAnalysis "{params,returnObj}" -x 3
 
# 观察方法入参. 对比前一个例子,返回值为空(事件点为方法执行前,因此获取不到返回值)
watch com.answer.ai.controller.OcrController asyncAnalysis "{params,returnObj}" -x 2 -b

# 同时观察方法调用前和方法返回后. -n 2: 表示只执行两次
watch com.answer.ai.controller.OcrController asyncAnalysis "{params,returnObj}" -x 2 -s -n 2

# -e: 表示抛出异常时才触发
watch com.answer.ai.controller.OcrController asyncResultGet '{params[0]}' -e -x 2
# 抛出异常时打印一次信息. 异常信息的变量是: throwExp
watch com.answer.ai.controller.OcrController asyncResultGet '{throwExp}' -e -x 3

# 按照耗时进行过滤. 只有当耗时大于20ms时才会输出,过滤掉执行时间小于200ms的调用
watch com.answer.ai.controller.OcrController asyncAnalysis '{params, returnObj}' '#cost>20' -x 2


# 观察当前对象中的属性. 如果想查看方法运行前后,当前对象中的属性,可以使用target关键字,代表当前对象
watch com.answer.ai.controller.OcrController asyncAnalysis 'target'
# 访问当前对象的某个属性(eg: requestId)
watch com.answer.ai.controller.OcrControllcAnalysis 'target.requestId'

# 异步挂起任务, 当存在异常时写入日志
watch com.answer.ai.controller.OcrController asyncAnalysis '{params,returnObj,throwExp}' -n 5 -x 3 'throwExp != null' > exception.log &

PS: 挂起任务使用 jobs 命令查看当前挂起的任务, kill job_id 指令杀死任务

monitor

方法执行监控

# 监控 asyncAnalysis 方法的执行
monitor com.answer.ai.controller.OcrController asyncAnalysis

# 每隔 5 秒统计一次. -c: 统计周期,默认值为 60 秒
monitor com.answer.ai.controller.OcrController asyncAnalysis -c 5

# 监控 OcrController 类中的所有方法. -n: 统计 5 次后退出
monitor com.answer.ai.controller.OcrController * -c 30 -n 5

# 挂起监控,  查看监控日志: cat /tmp app.log
monitor com.answer.ai.controller.OcrController * -c 5 > app.log &
# 使用 jobs 命令查看当前挂起的任务,  kill job_id 指令杀死任务

输出形式

 timestamp            class                                             method        total  success  fail  avg-rt(ms)
--------------------------------------------------------------------------------------------------------------------------------------------------
 2020-06-03 16:58:48  com.answer.ai.controller.OcrController            asyncAnalysis  1      1        0     2216.13

dump

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

# dump XloUtil 类到指定目录
dump com.answer.ai.util.XloUtil

# dump com.answer.ai.util 包下的所有类到指定目录
dump com.answer.ai.util.*

# -d: 指定输出目录
dump -d ./ com.answer.ai.util.XloUtil

heapdump

dump java heap, 类似jmap命令的heap dump功能

# dump到临时文件
heapdump

# dump到指定文件
heapdump ./dump.hprof

# 只dump live对象
heapdump --live ./dump.hprof

stack

输出当前方法被调用的调用路径

# 监控当前方法的调用路径
stack com.answer.ai.util.JacksonUtil parseObject

# -n: 执行次数限制, 达到次数后退出
stack com.answer.ai.util.JacksonUtil parseObject -n 2

需要调用接口并且接口中会调用到监控的方法

trace

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

trace com.answer.ai.controller.OcrController asyncAnalysis

# -j: 过滤掉jdk的函数
trace -j com.answer.ai.controller.OcrController asyncAnalysis

# #cost: 方法执行耗时, 只会展示耗时大于 50ms 的调用路径,有助于在排查问题的时候,只关注异常情况
trace -j com.answer.ai.controller.OcrController asyncAnalysis '#cost > 50'

trace 能方便的帮助你定位和发现因 RT 高而导致的性能问题缺陷,但其每次只能跟踪一级方法的调用链路。

tt

记录下指定方法每次调用的入参和返回信息。 方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测

# 记录下当前方法的每次调用环境现场
tt -t com.answer.ai.controller.OcrController asyncAnalysis

# 查看具体某个 INDEX 的调用信息, INDEX: 为返回的表格的 时间片段记录编号(index) 字段
tt -i <INDEX>

# 检索调用记录
tt -l
# 筛选出 asyncAnalysis 方法的调用信息
tt -s 'method.name=="asyncAnalysis"'
  • 解决方法重载
  • tt -t *Test print params.length==1
  • 通过制定参数个数的形式解决不同的方法签名,如果参数个数一样,你还可以这样写
  • tt -t *Test print ‘params[1] instanceof Integer’
  • 解决指定参数
  • tt -t *Test print params[0].mobile==“13989838402”

tt -t结果表格字段说明

表格字段 字段解释
INDEX 时间片段记录编号,每一个编号代表着一次调用,后续tt还有很多命令都是基于此编号指定记录操作,非常重要。
TIMESTAMP 方法执行的本机时间,记录了这个时间片段所发生的本机时间
COST(ms) 方法执行的耗时
IS-RET 方法是否以正常返回的形式结束
IS-EXP 方法是否以抛异常的形式结束
OBJECT 执行对象的hashCode(),注意,曾经有人误认为是对象在JVM中的内存地址,但很遗憾他不是。但他能帮助你简单的标记当前执行方法的类实体
CLASS 执行的类名
METHOD 执行的方法名

options

全局开关

# 查看全局开关信息
options

# 打开执行结果存日志功能, ${user.home}/logs/arthas-cache/result.log
options save-result true

vmoption

查看,更新VM诊断相关的参数

# 查看所有的option
vmoption

# 查看指定的option
vmoption PrintGC

# 更新指定的option
vmoption PrintGC true

 

参考网址

  • Arthas(阿尔萨斯) 官方用户文档
  • Arthas 命令列表
  • 使用arthas tunnel server连接远程arthas
  • Arthas IDEA插件
    • 插件地址: https://plugins.jetbrains.com/plugin/13581-arthas-idea
    • 使用文档: https://www.yuque.com/docs/share/fa77c7b4-c016-4de6-9fa3-58ef25a97948?#

你可能感兴趣的:(JVM,问题排查,教程类)