初探 Arthas 诊断工具

1,679 阅读2分钟

Arthas 是阿里推出的一款线上诊断工具,可以快速调试线上的应用程序,比如查看JVM信息、线程运行状态、方法的输入输出执行时间等。更强大的是,Arthas 还能做一些动态的更新,例如修改日志级别、热更新线上代码等。本文主要梳理了一下Arthas 一些常用的命令和分析案例。

安装

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

可选 idea 插件:arthas idea

该插件可以生成一些简单的命令模板,方便使用。

常用命令

PS D:\> java -jar .\arthas-boot.jar
[INFO] arthas-boot version: 3.4.3
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 21464 com.example.seed.SeedApplication

启动 arthas 后,选择对应的进程,attach 到目标进程后,就可以进入 arthas 命令行了。

同事还提供 UI,可访问 http://127.0.0.1:8563/

  1. dashboard
# 查看程序运行的所有信息(线程、内存、GC、runtime)
  1. thread
# 查看所有线程

thread -n 3 -i 5000
# 查看 5 秒内的 CPU 使用率 top n 的线程栈

thread -b
# 查看线程是否有阻塞
  1. sc
# 查找 JVM 加载类

sc *Controller
# 查找 Controller 结尾的类

sc -d com.example.seed.controller.ApiController
# 打印出类加载的具体信息

sc -d -f com.example.seed.controller.ApiController
# 同时打印该类注入字段的信息
  1. sm
# 查看已加载类的方法信息

sm java.lang.String
# 添加 - d 可打印每个方法的信息(入参、返回、异常)
  1. watch
# 监控方法的输入输出和抛出的异常

watch com.example.seed.controller.ApiController parserJson '{params,returnObj,throwExp}' -x 2
# 监控 ApiController 中的 parserJson,打印参数。返回结果、异常,
# -x 表示遍历深度,可以调整来打印具体的参数和结果内容,默认值是 1
  1. trace
# 监控方法性能,输出方法路径上的每个节点上耗时

trace com.example.seed.controller.ApiController parserJson
# 监控 parserJson 的链路耗时,循环的方法会一起进行统计
# 注意 lambda 或 stream 等操作可能无法进行 trace
# `---[16004.1213ms] com.example.seed.controller.ApiController:dd()
#        +---[min=999.517ms,max=1000.8083ms,total=5001.7296ms,count=5] com.example.seed.controller.ApiController:foo() #77
#        +---[min@=2000.4225ms,max=2000.6947ms,total=6001.7719ms,count=3] com.example.seed.controller.ApiController:bar() #79
#        `---[5000.3329ms] com.example.seed.controller.ApiController:kk() #82

trace com.example.seed.controller.ApiController parserJson '#cost > 10'
# 可添加 ognl 表达式,过滤 cost <= 10ms 的方法
  1. monitor
# 监控方法调用

monitor com.example.seed.controller.ApiController parserJson -c 10
# 监控 parserJson 10s 为一个周期,可以统计方法调用的次数、成功次数、失败次数、平均耗时
  1. jad
# 反编译代码

jad com.example.seed.controller.ApiController parserJson
# 可选择反编译整个 class 或只反编译某个方法
  1. 保存输出结果到本地
options save-result true

# 结果会异步保存在:{user.home}/logs/arthas-cache/result.log

一些案例

方法调用异常

线上服务出现问题,日志输出的又不是特别的明确,可通过 watch 命令,查看方法的输入输出和抛出的异常信息。

Arthas 排查函数调用异常 案例

动态改变 Logger Level

线上一般是不开debug的日志的,但是一旦遇到问题需要线上查错时,就需要更多的日志信息才能更好的定位错误。利用Arthas ,我们就可以动态修改logger的level,而不需要重新部署代码。

  1. 查找对应类的 ClassLoader
sc -d com.example.seed.controller.ApiController
#  class-info        com.example.seed.controller.ApiController
# class-loader      +-sun.misc.Launcher$AppClassLoader@18b4aac2
#                     +-sun.misc.Launcher$ExtClassLoader@17d99928
# classLoaderHash   18b4aac2
  1. 找到对应的 logger
ognl -c 18b4aac2 @com.example.seed.controller.ApiController@log
#@Logger[
#    serialVersionUID=@Long[5454405123156820674],
#    FQCN=@String[ch.qos.logback.classic.Logger],
#    name=@String[com.example.seed.controller.ApiController],
#    level=null,
#    effectiveLevelInt=@Integer[20000],
#    parent=@Logger[Logger[com.example.seed.controller]],
#    childrenList=null,
#    aai=null,
#    additive=@Boolean[true],
#    loggerContext=@LoggerContext[ch.qos.logback.classic.LoggerContext[default]],
#]
  1. 修改入日志级别
# 修改当前 controller 的 logger 日志级别
ognl -c 18b4aac2 @com.example.seed.controller.ApiController@log.setLevel(@ch.qos.logback.classic.Level@DEBUG)

# 修改全局日志级别
ognl -c 18b4aac2 @@org.slf4j.LoggerFactory@getLogger("root").setLevel(@ch.qos.logback.classic.Level@DEBUG)

热更新代码

这也是一个比较实用的功能,如果发现问题并且改动比较小的话,可以直接进行热更新。

  1. 反编译 class 为 java 代码
# --source-only 仅输出源码,不输出 ClassLoader 信息,并保存到 / tmp/ApiController.java
jad --source-only com.example.seed.controller.ApiController > /tmp/ApiController.java
  1. 修改代码后重新编译成 class
sc -d com.example.seed.controller.ApiController
mc -c 1be6f5c3 /tmp/UserController.java -d /tmp
  1. refine 到线上环境
redefine /tmp/example/seed/demo/controller/UserController.class

IDEA Plugin

Arthas 由比较多的命令行组成,记忆性的东西比较多,为了简化使用,可以在 idea 中安装 arthas idea plugin。插件可以在相应的方法上右键生成对应的诊断命令,然后粘贴到 arthas bash 中就可以运行了。

总结

Arthas 是一个功能强大的线上诊断工具,本文整理了一些常用的功能,在此基础上还有一些高级的,例如对线程和JVM垃圾回收的监控信息等,后期可以再深入学习一下。同时,我们可以配合idea plugin插件使用,更能事半功倍。