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插件执行流程
- 根据用户选择的源文件找到class文件,默认在/target/classes路径下面查找,用户也可以直接选择class文件;
- 使用AES-128加密class文件,输出base64编码;
- 加密的class文件上传至oss,返回oss访问地址;
- 渲染热部署需要执行的脚本,渲染后的脚本也上传至oss,返回oss访问地址;
- 组装热部署命令,并自动复制到粘贴板。
远程服务端热部署执行流程
- 登录远程服务器,粘贴热部署命令并执行;
- 下载热部署脚本,MD5验证热部署脚本,执行热部署脚本;
- 创建工作空间;
- 检查是否安装openssl,没有安装则进行安装;
- 下载AES-128加密的class文件;
- 使用openssl enc解密得到class二进制文件;
- 通过脚本方式安装arthas;
- 创建与arthas通信的管道并启动arthas;
- arthas选择java进程,默认选择第一个,也可以用户指定;
- arthas执行redefine命令热替换class文件;
- 打印热替换结果。