Skip to content

Arthas

快速导航:arthas 快速下载:arthas-packaging-4.3.2-bin.zip

🛠️ 核心命令速查表

这是 Arthas 最常用的一些命令,可以帮你快速上手。

命令 作用 示例
dashboard 展示当前系统的实时数据面板,包括线程、内存、GC、运行环境等信息。 dashboard
thread 查看线程信息,是排查CPU飙升、死锁等问题的利器。 thread -n 3 (查看最忙的3个线程)
thread -b (找出当前阻塞其他线程的线程)
jad 将 JVM 中实际运行的类的字节码反编译成 Java 代码。 jad java.lang.String
watch 最常用的命令之一。观测方法执行的数据,包括入参、返回值、抛出异常等。 watch com.example.MyClass myMethod "{params, returnObj}" -x 2
trace 追踪方法内部调用路径,并输出路径上每个节点的耗时,用于性能分析。 trace com.example.MyClass myMethod
jvm 查看当前 JVM 的详细信息,如内存区域、GC机制、类加载器等。 jvm
sc 查看 JVM 中已加载的类信息。 sc com.example.* (查找指定包下的所有类)
quit/exit 退出当前 Arthas 客户端连接,但 Arthas 服务端仍在目标进程中运行。 quit
stop 完全退出 Arthas,并卸载其在目标进程中的 Agent。 stop

火焰图

【纵轴(Y轴)】表示的是方法调用的调用栈信息,即从最外层方法到最内层方法的调用信息。 【横轴(X轴)】表示的是方法调用的持续时间,即方法在执行过程中所占用的时间长度。 在一个火焰图中,越靠近下面的函数在x轴上越长是正常的,而越往上的函数就应该越短。所以,火焰图也像是一个个山峰。那么,如果火焰图出现较宽的峰顶,那就往往是性能瓶颈。

使用Arthas

安装Arthas

Arthas 支持在 Linux/Unix/Mac 等平台上一键安装,请复制以下内容,并粘贴到命令行中,敲 回车 执行即可。

curl -L https://arthas.aliyun.com/install.sh | sh

运行Arthas

上述命令会下载启动脚本文件 as.sh 到当前目录,直接在shell下面执行./as.sh,就会进入交互界面。

执行观测方法命令

watch com.**.**.endpoint.BargainPlayApplyCycleEndPoint fetchPlayDetailRenderData '{params,returnObj,throwExp}' -n 5 -x 3 'params[0].getPlayToolDO().getId()==588'

命令解释:'{params,returnObj,throwExp}' 表示观测对象,这里选择了入参、出参和异常,-n 5 表示观测到5次后停止,-x 3 表示打印观测对象的时候只打印3层嵌套结构,'params[0].getPlayToolDO().getId()==588' 为条件表达式,满足该条件的才会被观测到。

方法执行的时间隧道

获取tt命令

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

安装好arthas idea插件之后,在需要记录执行的方法上面单击右键,选择TimeTunnel Tt,出现下面的选择框,第一个红框是获取记录方法执行的命令。第二个红框是记录方法执行之后需要对记录进行的操作,包括查看记录列表、查看记录执行情况、重现调用等。

记录方法执行

登录远程服务器,运行以下两条运行arthas,然后执行从idea插件复制的tt -t命令来记录方法执行,如下图所示。如果想停止记录可以输入q,查看记录使用tt -l。

curl -L https://arthas.aliyun.com/install.sh | sh
./as.sh

搜索方法执行记录

tt -l可以查看所有的方法执行记录,但是我们要和我们相关的执行记录,那么可以使用tt -s命令进行搜索。
tt -s 命令后面需要携带过滤条件。条件表达式是使用OGNL编写,下面介绍几个通常的过滤表达式。

首先介绍下几个对象,params表示入参,params[0]表示第一个参数,params[1]表示第二个参数,returnObj表示返回对象。 - 根据入参过滤:tt -s 'params[2].getRecordId() == 110213603' - 根据返回结果过滤:tt -s 'returnObj.isSuccess() == false' - 根据入参和返回结果过滤:tt -s 'returnObj.isSuccess() == true && params[2].getRecordId() == 110213603'

查看方法执行情况

tt -w 相当于tt下面的watch命令,可以用来查看方法执行情况。使用idea插件获取tt -w 命令更方便。

重新触发

如果需要重新触发某条记录也是可行的,因为tt命令记录当时调用的情况,所以可以本地发起一次调用,tt -p -i 1000 命令的意思重新触发 index=1000 的那条记录。 不仅仅可以重新触发,还可以间隔时间内多次触发,tt -p --replay-times 5 --replay-interval 2000 -i 1000 表示重新触发5次,每次间隔2s。

重新触发的时候我们可能还想再watch下方法执行情况,怎么办呢,另外再打开一个页面登录远程服务器,运行arthas,执行 watch 命令。

注意事项

ThreadLocal 信息丢失

很多框架偷偷的将一些环境变量信息塞到了发起调用线程的 ThreadLocal 中,由于调用线程发生了变化,这些 ThreadLocal 线程信息无法通过 Arthas 保存,所以这些信息将会丢失。一些常见的 CASE 比如:鹰眼的 TraceId 等。

引用的对象

需要强调的是,tt 命令是将当前环境的对象引用保存起来,但仅仅也只能保存一个引用而已。如果方法内部对入参进行了变更,或者返回的对象经过了后续的处理,那么在 tt 查看的时候将无法看到当时最准确的值。这也是为什么 watch 命令存在的意义。

热部署:ArthasHotSwap

ArthasHotSwap原理

Arthas 是阿里巴巴开源的Java代码诊断工具。Arthas 的 redefine 命令是基于JDK Instrumentation API实现的热部署。Arthas的redefine命令其实是把Instrumentation API的redefineClasses方法包装后提供给用户,那么我们就可以根据redefine命令发挥想象力,实现热部署。 Arthas官方文档推荐使用jad/mc/redefine等一连串命令实现class远程热替换,流程大概是:jad命令对老class进行反编译->vim编辑源码->mc命令编译源码->redefine热替换class。 这种方式存在两个问题:一是太麻烦,二是mc编译大概率会失败。如果能这样就好,本地修改代码编译后上传class文件到远程服务器,再使用redefine命令热替换class。因此官方文档又推荐,首先将 class 二进制文件转换成 base64 编码,然后再复制粘贴到远程服务器,再把 base64 编码转换成 class 文件,最后,使用 redefine 进行热替换。这么麻烦,还不如重新部署呢。所以redefine命令比较鸡肋。

ArthasHotSwap插件执行流程

  1. 根据用户选择的源文件找到class文件,默认在/target/classes路径下面查找,用户也可以直接选择class文件;
  2. 使用AES-128加密class文件,输出base64编码;
  3. 加密的class文件上传至oss,返回oss访问地址;
  4. 渲染热部署需要执行的脚本,渲染后的脚本也上传至oss,返回oss访问地址;
  5. 组装热部署命令,并自动复制到粘贴板。

远程服务端热部署执行流程

  1. 登录远程服务器,粘贴热部署命令并执行;
  2. 下载热部署脚本,MD5验证热部署脚本,执行热部署脚本;
  3. 创建工作空间;
  4. 检查是否安装openssl,没有安装则进行安装;
  5. 下载AES-128加密的class文件;
  6. 使用openssl enc解密得到class二进制文件;
  7. 通过脚本方式安装arthas;
  8. 创建与arthas通信的管道并启动arthas;
  9. arthas选择java进程,默认选择第一个,也可以用户指定;
  10. arthas执行redefine命令热替换class文件;
  11. 打印热替换结果。