java之agent

java之agent

我们平时用的很多工具,都是基于Java Agent实现的,例如常见的热部署JRebel,各种线上诊断工具(btrace, greys), APM , eg new relic, Profiling Yourkit etc..

Java Agent也是一个jar,只是启动方式和普通Jar包有所不同,对于普通的Jar包,通过指定类的main函数进行启动,但是Java Agent并不能单独启动,必须依附在一个Java应用程序运行

java agent技术的主要功能如下:

  • 可以在加载java文件之前做拦截把字节码做修改
  • 可以在运行期将已经加载的类的字节码做变更

通过java agent技术进行类的字节码修改最主要使用的就是Java Instrumentation API。

启动加载

在目标JVM运行时加载

[1] public static void premain(String agentArgs, Instrumentation inst);
[2] public static void premain(String agentArgs);

启动参数增加-javaagent:[path],其中path为对应的agent的jar包路径

Screen Shot 2020-09-04 at 10.50.50 PM

  • 创建InstrumentationImpl对象
  • 监听ClassFileLoadHook事件
  • 调用InstrumentationImpl的loadClassAndCallPremain方法,在这个方法里会去调用javaagent里MANIFEST.MF里指定的Premain-Class类的premain方法

运行时加载

[1] public static void agentmain(String agentArgs, Instrumentation inst);
[2] public static void agentmain(String agentArgs);

使用com.sun.tools.attach.VirtualMachine加载

try {
String jvmPid = 目标进行的pid;
logger.info("Attaching to target JVM with PID: " + jvmPid);
VirtualMachine jvm = VirtualMachine.attach(jvmPid);
jvm.loadAgent(agentFilePath);//agentFilePath为agent的路径
jvm.detach();
logger.info("Attached to target JVM and loaded Java agent successfully");
} catch (Exception e) {
throw new RuntimeException(e);
}

运行时修改主要是通过jvm的attach机制来请求目标jvm加载对应的agent

  • 创建InstrumentationImpl对象
  • 监听ClassFileLoadHook事件
  • 调用InstrumentationImpl的loadClassAndCallAgentmain方法,在这个方法里会去调用javaagent里MANIFEST.MF里指定的Agentmain-Class类的agentmain方法

Instrumentation

https://www.baeldung.com/java-instrumentation

java.lang.instrument.Instrumentation

  • addTransformer – adds a transformer to the instrumentation engine
  • getAllLoadedClasses – returns an array of all classes currently loaded by the JVM
  • retransformClasses – facilitates the instrumentation of already loaded classes by adding byte-code
  • removeTransformer – unregisters the supplied transformer
  • redefineClasses – redefine the supplied set of classes using the supplied class files, meaning that the class will be fully replaced, not modified as with retransformClasses

instrument是JVM提供的一个可以修改已加载类的类库,专门为Java语言编写的插桩服务提供支持。

redefineClasses和retransformClasses。一个是重新定义class,一个是修改class。

可使用ASM或Javassist对传入的字节码进行改写或替换

案例

https://mp.weixin.qq.com/s/ArP0CtVZMB2oUYSdjr7RGw

通过 asm 在方法的执行入口和执行出口处,植入几行记录时间戳的代码,当方法结束后,通过时间戳来获取方法的耗时。

public static void premain(String args, Instrumentation instrumentation) {
instrumentation.addTransformer(new TimeClassFileTransformer());
}

我们通过 instrumentation.addTransformer 注册一个转换器,转换器重写了 transform 方法,方法入参中的 classfileBuffer 表示的是原始的字节码,方法返回值表示的是真正要进行加载的字节码。

远程采集已经处于运行中的 Java 进程的方法调用信息。

  • agent 对指定类的方法进行字节码的修改,采集方法的入参和返回值。并通过 socket 将请求和返回发送到服务端
  • 服务端通过 attach api 访问运行中的 Java 进程,并加载 agent ,使 agent 程序能对目标进程生效
  • 服务端加载 agent 时指定需要采集的类和方法
  • 服务端开启一个端口,接受目标进程的请求信息

summary

java agent is just a specially crafted jar file. It utilizes the Instrumentation API that the JVM provides to alter existing byte-code that is loaded in a JVM.

For an agent to work, we need to define two methods:

  • premain – will statically load the agent using -javaagent parameter at JVM startup
  • agentmain – will dynamically load the agent into the JVM using the Java Attach API

Misc

Java 调试、热部署、JVM 背后的都是通过 Java Agent

-各个 Java IDE 的调试功能,例如 eclipse、IntelliJ ; -热部署功能,例如 JRebel、XRebel、 spring-loaded; -各种线上诊断工具,例如 Btrace、Greys,还有阿里的 Arthas; -各种性能分析工具,例如 Visual VM、JConsole 等;

例如: JMX

用了 management-agent.jar 这个Java Agent 来实现的

如果服务允许远程查看JVM 信息:

-Dcom.sun.management.jmxremote
-Djava.rmi.server.hostname=192.168.1.1
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.rmi.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

management-agent.jar 包下MANIFEST.MF

Manifest-Version: 1.0
Created-By: 1.7.0_07 (Oracle Corporation)
Agent-Class: sun.management.Agent
Premain-Class: sun.management.Agent

https://mp.weixin.qq.com/s/nFoxGH7mGt20P0e5rcZivQ

https://mp.weixin.qq.com/s/_JqxUmQKvUpUulmcSMQq2A

https://zhuanlan.zhihu.com/p/101828645

https://zhuanlan.zhihu.com/p/82164274