Arthas整体架构初探!
共 4221字,需浏览 9分钟
·
2023-10-31 22:26
你知道的越多,不知道的就越多,业余的像一棵小草!
你来,我们一起精进!你不来,我和你的竞争对手一起精进!
编辑:业余草
来源:juejin.cn/post/7182967420544352315
推荐:https://t.zsxq.com/13Bzo3HUh
自律才能自由
开篇
Arthas是Alibaba开源的Java诊断工具,日常用这个工具排查很多问题,例如:类冲突问题、接口耗时很长问题、线程池阻塞问题等等,arthas还支持获取堆中对象、执行对象方法、修改对象属性值,真的是有了Arthas便可为所欲为!
当前对它的命令还算比较熟练了,想再进一步了解一下这个神器,学习它的原理和设计。
Arthas用到了JVM Attach API、Java agent、JVMTI、ClassLoader类隔离等技术,后面我们将跟着Arthas源码去探索一下神器是如何巧妙地使用这些手段。
本文,将从了解Arthas项目整体结构开始。
初探Arthas项目结构
![](https://filescdn.proginn.com/b32886233b147e212871831de97a105a/359299a8acd1ee1d0f7e256625c0930a.webp)
源码工程结构
先从github上clone最新的Arthas源码,地址:https://github.com/alibaba/arthas
。
![](https://filescdn.proginn.com/6ff3be39b4ac38304312cd56ce32a8ff/405dc167374dc4c2c27aea02a0d65dc2.webp)
从github上看到Arthas源码约74%是Java写的,看到这就放心了,源码理解起来应该不会很费劲。
再将源码导入IDEA,项目结构如下:
![](https://filescdn.proginn.com/efeecdb1a4cd58d12811ac1dc5a0edc9/79c246541f25dfae97059d4d0fc0a869.webp)
模块比较多,我们挑重点讲解一下:
模块 | 功能 |
---|---|
agent | Java agent的模块 |
arthas-vmtool | vmtool命令由这个模块实现 |
async-profiler | 火焰图相关 |
boot | 启动入口 |
core | 核心功能模块,包括:1.attach宿主应用进程,load arthas-agent 2.核心命令的实现 3.和arthas-client通信 |
math-game | 一个测试用的demo |
memorycompiler | 字节码编译。 |
packaging | 定义项目打包的规则 |
spy | 只包含Spy类,简单理解为实现类似spring aop的Advice,有前置方法,后置方法等 |
tunnel-client、tunnel-common、tunnel-server | tunnel-server/tunnel-client 实现远程管理/连接多个 Agent |
web-ui | Web Console用到的前端资源 |
打包后工程结构
在github上下载RELEASE包,地址: https://github.com/alibaba/arthas/releases
,下载「arthas-bin.zip」文件。解压文件,可以看到打包后的项目结构:
![](https://filescdn.proginn.com/fdc192ecfb316a3cd98c95ac453ec178/cc08dd55f68b1de328862b899483da6e.webp)
其中,重点关注其中的jar包。
模块 | 功能 |
---|---|
arthas-agent.jar | 是一个Java agent的jar,支持Attach API 方式被动态加载,也支持-javaagent: 方式被静态加载 |
arthas-boot.jar、as.sh、as.bat | 启动入口 |
arthas-client.jar | 客户端程序,用来连接挂载于宿主应用进程的arthas-core |
arthas-core.jar | 核心功能模块,包括:1.attach宿主应用进程,load arthas-agent 2.核心命令的实现 3.和arthas-client通信 |
arthas-spy.jar | 只包含Spy类,简单理解为实现类似spring aop的Advice,有前置方法,后置方法等 |
math-game.jar | 一个测试用的demo |
核心模块
arthas-boot、as.sh、as.bat
arthas-boot、as.sh、as.bat功能类似,arthas-boot是java的方式,可以通过jar -jar arthar-boot.jar启动arthas服务端,而as.sh是通过脚本的方式启动arthas服务端。我们用java -jar arthas-boot.jar启动或者as.sh启动,会加载出下面的界面:
![](https://filescdn.proginn.com/8a31c23da3948806940fdc7573c4abfc/e6d67d64c4ca157b63f26d1d5a3b4573.webp)
arthas-core
arthas-boot里启动类com.taobao.arthas.boot.Bootstrap用到了通过java -jar arthas-core.jar启动子进程,
这个子进程只会短暂存在。该进程的信息示例:
MacBook-Pro:arthas-github terry$ ps -ef|grep arthas-core
503 43456 43321 0 10:35PM ?? 0:00.23 /Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/../bin/java -Xbootclasspath/a:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/../lib/tools.jar -jar /Users/terry/software_developmet_1/arthas/arthas-bin-3.6.7/arthas-core.jar -pid 43120 -core /Users/terry/software_developmet_1/arthas/arthas-bin-3.6.7/arthas-core.jar -agent /Users/terry/software_developmet_1/arthas/arthas-bin-3.6.7/arthas-agent.jar
java -jar arthas-core.jar运行时,会执行com.taobao.arthas.core.Arthas#main,然后解析参数,attach到目标进程,目标进程挂载arthas-agent.jar,arthas-agent的premain方法com.taobao.arthas.agent334.AgentBootstrap#premain会执行,然后加载arthas-core.jar【多次出现arthar-core.jar,感觉设计不是很好,应该分离多个模块】,此时会调用com.taobao.arthas.core.server.ArthasBootstrap,com.taobao.arthas.core.server.ArthasBootstrap会加载spy.jar
arthas-client
arthas-client是arthas客户端,支持通过telnet的方式连接到arthas服务端。
arthas-agent
一个Java agent的jar,支持Attach API
方式被动态加载,也支持-javaagent:
方式被静态加载。arthas-agent的premain或者agentmain方法会执行com.taobao.arthas.agent334.AgentBootstrap#main会执行,然后加载arthas-core.jar
arthas-spy
arthas-core.jar被挂载到宿主应用的进程后,arthas-core会让BootstrapClassLoader去加载arthas-spy.jar。该模块只包含Spy类,简单理解为实现类似spring aop的Advice,有前置方法,后置方法等。
小结
本文简述了 arthas 的项目结构和核心模块,感兴趣的网友可以自行梳理一下 arthas 启动流程。当然我后面也会继续给大家输出这方面的内容!