欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Arthas源码解析

程序员文章站 2022-07-13 14:58:01
...

 Arthas源码解析:

首先是arthas的工程结构:

arthas-agent:javaagent包,需要将此包与被监控程序通过javaagent一起启动,也可以通过虚拟机loadagent来植入增强代码

arthas-boot:arthas启动主程序,arthas推荐的启动方式

arthas-client:telnet连接工程

arthas-client:arthas核心包,里面也有主方法可以启动arthas

arthas-spy:间谍程序,该包由启动类加载器加载,其他工程包由arthas自定义类加载器加载

一、从arthas-core中的Arthas看起:

1.Arthas.java中的主方法是启动方法,会执行到attachAgent(),我们从这个方法看起,这里的configure中有参数为被监控程序的pid

拿到pid后通过VirtualMachine.attach来链接到目标虚拟机

2.连接到虚拟机后判断jdk版本,设置agent包路径,然后通过 virtualMachine.loadAgent(agent包路径, 参数)来远程加载agent,

这里的参数会传到preagent方法中的args中。

二、对目标虚拟机执行loadagent后,目标虚拟机会加载agent程序,通过绝对路径找到arthas-agent包,执行agentmain方法(如果通过-javaagent

参数进行增强,则是执行premain方法),方法最终执行main方法,main方法主要执行了一些初始化工作

1.首先通过传入参数找到agentjar和spyjar,通过Instrumention的appendToBootstrapClassLoaderSearch方法将spyjar加入到被监控程序的

启动类加载器搜索路径中,然后定义自己的类加载器,加载agentjar(这里的agentjar就是arthas-core包)

2.接着初始化间谍程序,通过自定义的classloader找到com.taobao.arthas.core.advisor.AdviceWeaver类,然后获取它的methodOnBegin,

methodOnReturnEnd,methodOnThrowingEnd...等方法,然后将他们植入(赋值)给spy,之后就是新启一个现成来进行绑定操作

3.绑定操作最终执行的是com.taobao.arthas.core.server.ArthasBootstrap的bind方法,首先通过相关的配置,参数对ShellServerImpl进行

初始化,接着设置预置命令BuiltinCommandPack,后面是两种监听方式,一种是telnet,一种是http也就是websocket,最后有一行

//监听

            shellServer.listen(new BindHandler(isBindRef));就是注册监听器了。我们来看telnet的TelnetTermServer中有一个listen方法,这里就是监听命令了

4.最后执行UserStatUtil.arthasStart();这只是一个统计,可以不用管

三、接下来就是监听命令以及处理命令了

1.在 shellServer.listen(new BindHandler(isBindRef))中,可以看到初始化了一个TermServerListenHandler,初始化后赋值给TermServer,

方法内部通过启动一个netty telnet端口来进行监听,Helper.loadKeymap()这个方法主要是在项目目录inputrc文件里加载对应的快捷键以及对应的

处理类name标识,返回个映射对象,对命令行界面快捷键指示处理需要。

2.new TermImpl构造方法中,首先静态对象readlineFunctions是所有的Function接口的子类,Helper.loadServices方法里面的 ServiceLoader.load

其实就是根据META-INF下的Servides文件夹下的文件来读取实现类,接着实现DefaultTermStdinHandler,EventHandler以及对应的赋值,结合term

框架可以对相应的快捷键进行处理

3.回到TermServer.listen方法中,有初始化实例TermServerTermHandler ,启动监听后的termhandler.handle方法,就是该实例的hanle方法,

而该handler中的handle方法执行了handleTerm,这里对session进行了初始化,包括欢迎语,然后readline就是等待用户输入了,

4.当用户输入help时, 最中会调用ShellLineHandler.handle方法,这里做了前置的文件检查及解析,help命令顺利到了createjob这一步,一层层的封装,

然后创建实例化CommandProcess,这里要注意的是,找到command对应的processhandler赋值给ProcessImpl的属性了,这里就埋下伏笔,为后面路由

找到HelpCommand具体流程:createJob() -> createProcess() -> getCommand() 创建完job后,对job启动

这里启动后的执行流程为 job.run() ->   process.run(foreground) ->  ArthasBootstrap.getInstance().execute(task)(这里的task是关键

Runnable task = new CommandProcessTask(process); 最后调用的是CommandProcessTask的run方法) ->handler.handle(process)(这里的handler

是processhandler) -> process() ->instance.process(process)(这里的instance就是具体的命令实现了)

四、详细命令解析

 

 

--后续补充

 

 

 

 

 

 

相关标签: Arthas