Agent简介

    `Java Agent`可以理解为一个`JVM`虚拟机的插件,`agent`插件`jar`包通过`JVMTI`

完成加载,JVMTI全称JVM Tool Interface,是JVM暴露出来的一些供用户扩展的接口集合。JVMTI是基于事件驱动的,JVM每执行到一定的逻辑就会调用一些事件的回调接口(如果有的话),这些接口可以供开发者扩展自己的逻辑。最终借助JPLISAgent(Java Programming Language Instrumentation Services Agent)完成对目标代码的修改。

JVMTIAgent动态库提供以下函数:

启动时加载
JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM *vm, char *options, void *reserved);

运行时加载
JNIEXPORT jint JNICALL
Agent_OnAttach(JavaVM* vm, char* options, void* reserved);

卸载时调用
JNIEXPORT void JNICALL
Agent_OnUnload(JavaVM *vm);

Untitled

Agent启动时加载流程:

1.创建并初始化 JPLISAgent

2.监听 VMInit 事件,在 vm 初始化完成之后做下面的事情:

<aside> ✅ 创建 InstrumentationImpl 对象

</aside>

<aside> ✅ 监听 ClassFileLoadHook 事件loadClassAndCallPremain方法,在这个方法里会调用 javaagent 里 MANIFEST.MF 里指定的Premain-Class类的 premain 方法

</aside>

3.解析 javaagent 里 MANIFEST.MF 里的参数,并根据这些参数来设置 JPLISAgent里的一些内容

Agent打包

源码编译方式打包:

mvn -Dmaven.test.skip=true clean install -U
#目录下是agent的打包文件
cd femas-agent/femas-agent
文件目录
├── femas-agent 
│   ├── config #agent配置文件
|   |   ├── femas.yaml  #femas组件相关配置
|   |   ├── plugin.yaml  #premain需要加载的plugin相关配置
│   ├── plugins  #plugin jar包
|   |   ├── plugin.jar
│   └── femas-agent.jar  #-javaagent指向的jar

Agent使用

femas-agent包放在服务器的任意位置,在服务启动参数加上:

-javaagent:"/绝对路径/femas-agent.jar" //指向femas-agent文件夹中的femas-agent.jar