Arthas使用指北——命令、原理及案例

1 整合方式

当前普遍使用容器化的部署方式,两种方式部署到tke容器中

  • docker打包时将arthas打包进去
  • 在容器中下载
curl -O https://alibaba.github.io/arthas/arthas-boot.jar

boot包仅有一百多 KB

执行

java -jar arthas.jar

即可进入arthas命令行,选择正在执行的java进程后,即可对进程进行相应的在线检测、诊断与调试。

2 实现原理

2.1 Java Agent和Instrumentation

我们知道,IDE中的Debug是通过JDPA技术实现了对代码的远程调试控制。而生产环境中是不会提供给我们JDPA接口的,Arthas使用的是Java Agent技术。

Java Agent 又叫做 Java 探针,Java Agent 是在 JDK1.5 引入的,是一种可以动态修改 Java 字节码的技术。Java 类编译之后形成字节码被 JVM 执行,在 JVM 在执行这些字节码之前获取这些字节码信息,并且通过字节码转换器对这些字节码进行修改,来完成一些额外的功能,这种就是 Java Agent 技术。在许多文章中,Java Agent被描述为虚拟机级别的AOP

实际上单说Java Agent的话,并不涉及字节码的修改,Java Agent是运行在main方法之前的拦截器,它内定的方法名叫 premain ,也就是说要先执行premain再执行main方法。也就是说,Java Agent仅仅是作为代理,为我们提供了在main函数运行之前的一个入口。

public static void premain(String agentArgs, Instrumentation inst); 
public static void premain(String agentArgs);

Java Agent是一个概念,其具体的实现是借助于java.lang.instrument包。在JDK1.5中,Instrument 要求在运行前利用命令行参数或者系统参数来设置代理类,在实际的运行之中,虚拟机在初始化之时(在绝大多数的 Java 类库被载入之前), instrumentation 的设置已经启动,并在虚拟机中设置了回调函数,检测特定类的加载情况,并完成实际工作。但是在实际的很多的情况下,我们没有办法在虚拟机启动之时就为其设定代理,这样实际上限制了 instrument 的应用。而 Java SE 6 的新特性改变了这种情况,通过 Java Tool API 中的 attach 方式,通过VirtualMachine.attachVirtualMachine.loadAgent把agent attach到pid上,我们可以很方便地在运行过程中动态地设置加载代理类,以达到 instrumentation 的目的。而在运行时加载agent,就不再实现premain,而是实现agentmain这个方法。

public static void agentmain(String agentArgs, Instrumentation inst); 
public static void agentmain(String agentArgs);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ED3jyFvy-1662182362358)(https://km.woa.com/files/photos/pictures/202108/1630248252_2_w1082_h508.jpg)]
整个流程如上图所示,总共可分为如下六步。

  1. 在 JVM 启动时,通过 JVM 参数 -javaagent,传入 agent jar,Instrument Agent 被加载;
  2. 在 Instrument Agent 初始化时,注册了 JVMTI 初始化函数 eventHandlerVMinit
  3. 在 JVM 启动时,会调用初始化函数 eventHandlerVMinit,启动了 Instrument Agent,用 sun.instrument.instrumentationImpl类里的方法loadClassAndCallPremain 方法去初始化 Premain-Class 指定类的 premain 方法;
  4. 初始化函数 eventHandlerVMinit,注册了 class 解析的 ClassFileLoadHook 函数;
  5. 在解析 Class 之前,JVM 调用 JVMTIClassFileLoadHook 函数,钩子函数调用 sun.instrument.instrumentationImpl 类里的 transform 方法,通过TransformerManagertransformer 方法最终调用我们自定义的 Transformer 类的 transform 方法(在premainagentmain中指定);
  6. 因为字节码在解析 Class 之前改的,直接使用修改后的字节码的数据流替代,最后进入 Class 解析,对整个 Class 解析无影响;

对于我们通过attach的方式进行instrumentation,则是对class文件进行重新加载,走5、6两个步骤。

2.2 JVMTI

在2.1节中介绍了JVMTI,JVMTI全称JVM Tool Interface,是JVM暴露出来的一些供用户扩展的接口集合,JVMTI是基于事件驱动的,也就是JVM每执行到一定的逻辑时就会调用一些事件的回调接口(如果回调接口存在),这些接口就可以被开发者扩展自己的逻辑。JVMTIAgent 是一个利用 JVMTI 暴露出来的接口提供了代理启动时加载(agent on load)、代理通过attach形式加载(agent on attach)和代理卸载(agent on unload)功能的动态库。而 instrument agent 可以理解为一类 JVMTIAgent 动态库,别名是 JPLISAgent(Java Programming Language Instrumentation Services Agent) ,也就是 专门为java语言编写的插桩服务提供支持的代理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wPNKFPhi-1662182362359)(https://km.woa.com/files/photos/pictures/202108/1630251937_41_w1166_h688.png)]

2.3 ASM

另一个扮演了重要角色的工具就是我们经常使用的ASM,Java字节码操纵框架。Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。在许多Java项目中都能看到ASM的身影,比如CGLIB动态代理和lombok的@Data注解自动生成getter和setter。

在2.1节对字节码文件进行修改时,就是通过ASM直接修改class文件,以实现java程序的动态修改,如打印日志等。

3 常用命令

3.1 基础命令

help——查看命令帮助信息

cls——清空当前屏幕区域

reset——重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类

quit——退出当前 Arthas 客户端,其他 Arthas 客户端不受影响

stop——关闭 Arthas 服务端,所有 Arthas 客户端全部退出

3.2 jvm相关

dashboard——当前系统的实时数据面板,包含线程及内存信息

thread——查看当前 JVM 的线程堆栈信息

jvm——查看当前 JVM 的信息

ognl——执行ognl表达式

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

3.3 class/classloader相关

sc——search class查看JVM已加载的类信息

sm——search method查看已加载类的方法信息

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

mc——内存编译器,内存编译.java文件为.class文件

retransform——加载外部的.class文件,retransform到JVM里

classloader——查看classloader的继承树,urls,类加载信息,使用classloader去getResource

3.4 monitor/watch/trace相关

此类命令,都通过字节码增强技术来实现的,会在指定类的方法中插入一些切面来实现数据统计和观测,线上使用时需谨慎,尽量明确需要观测的类、方法以及条件,诊断结束要执行stop或将增强过的类执行 reset 命令。

4 优秀实践

Alibaba Arthas实践–获取到Spring Context,然后为所欲为 · Issue #482 · alibaba/arthas (github.com)

工商银行打造在线诊断平台的探索与实践

5 参考资料

官方文档

GitHub源码

Arthas运行原理 - 知乎 (zhihu.com)

Arthas在JAVA程序问题排查中的应用 - 质变 - KM平台 (woa.com)

深入理解Instrument(一) - 云+社区 - 腾讯云 (tencent.com)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值