Arthas源码分析

在日常开发中,经常会使用到arthas排查线上问题,觉得arthas的功能非常强大,所以打算花了点时间了解一下其实现原理。并试着回答一下使用Arthas时存在的一些疑问。

Arthas主要基于是Instrumentation + JavaAgent + Attach API + ASM + 反射 + OGNL等技术实现的。在不停止应用服务的情况下,将Arthas的jar包代码动态加载到应用的JVM中,再配合Instrumentation类,动态修改应用JVM中运营的字节码,实现对目标应用增强,如获取某方法的参数、返回值、耗时等信息、调用JVM相关类获取JVM运行时信息,最后再通过OGNL过滤、存取对象属性。

1. 如何attach到应用?

1.1 如何debug?

Arthas的启动很简单,从github上把Arthas的代码clone到本地,然后直接运行/bin目录下的as.sh脚本便能启动。为了弄明白Arthas attach到应用的过程,可以加上--debug-attach参数,同时为了查看脚本的详细执行流程,bash加上-x选项。

 

shell

复制代码

bash -x ./as.sh --debug-attach

根据打印的执行流程,开始主要是进行一些配置检查、目录创建和运行参数的构造。前置工作准备好后,会调用jps命令列出系统当前所有运行的JVM。

选择我们需要attach的JVM,会判断本地目录$HOME/.arthas/中是否存在Arthas对应版本的jar包,如果不存在,则下载并解压到指定目$HOME/.arthas/

最后通过java命令运行Arthas client,尝试连接Arthas server(127.0.0.1:3568)

 

shell

复制代码

java -agentlib:jdwp=transport=dt_socket,address=8888,server=y,suspend=y -Djava.awt.headless=true -jar /Users/banzhe/.arthas/lib/3.6.6/arthas/arthas-client.jar 127.0.0.1 3658 -c session --execution-timeout 2000

从启动的命令可以看到,主要是运行了arthas-client.jar包,同时开启了远程debug,远程debug端口号8888,因为设置了suspend=y,启动流程被阻塞,等待debugger attach。打开IDEA,配置远程debug,然后点击debug,流程即可继续。

因为当前Arthas server还没有启动(attach到应用JVM),所以抛了一个ConnectException异常

接着启动Arthas server,将其attach到指定的应用JVM

 

shell

复制代码

java -Xbootclasspath/a:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/lib/tools.jar -agentlib:jdwp=transport=dt_socket,address=8888,server=y,suspend=y -Djava.awt.headless=true -jar /Users/banzhe/.arthas/lib/3.6.6/arthas/arthas-core.jar -pid 57840 -core /Users/banzhe/.arthas/lib/3.6.6/arthas/arthas-core.jar -agent /Users/banzhe/.arthas/lib/3.6.6/arthas/arthas-agent.jar

从启动的命令可以看到,主要是运行了arthas-core.jar和arthas-agent.jar两个jar包,同时开启了远程debug,远程debug端口号8888。查看arthas-core和arthas-agent两个模块下的pom文件,可以发现main方法在arthas-core模块下的com.taobao.arthas.core.Arthas类中,所以在arthas-core模块的main方法设置断点,然后点击debug,即可开始attach过程的debug。

远程debug连接成功之后,attach流程就很容易弄明白了。attach的过程主要是在attachAgent中完成的。

1.2 Arthas attach到应用JVM

attach是使用sun提供JVM Attach API完成的。核心代码如下:

 

java

复制代码

VirtualMachineDescriptor virtualMachineDescriptor = null; // 1. 列出当前系统运行的所有JVM,和jps类似 for (VirtualMachineDescriptor descriptor : VirtualMac

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值