什么是agent
Java探针通常是指Java Agent
它是一种可以在JVM启动时或运行时加载的组件,用来修改或增强字节码,从而监控或改变程序的行为
agent应用在哪些方面
1.Arthas就是应用了我们的探针技术
2.代码热替换实现我们的热部署,Java Agent可以在类加载时修改字节码,从而实现热部署
3.数据脱敏,比如在应用层面对敏感数据进行加密或脱敏处理,可能通过修改相关方法的字节码,在数据返回前进行处理,比如在DAO层拦截结果集,对身份证号、手机号进行脱敏。
4.调用链跟踪,分布式系统中的链路追踪,比如SkyWalking框架,比如OpenTracing的实现,可能需要通过探针在服务调用的入口和出口添加跟踪代码,生成和传递TraceID,SpanID等信息,这样可以在分布式系统中追踪请求的路径
有些增强不需要agent,比如AOP的增强
某些框架可能使用Java Agent来实现切面编程,而不需要依赖Spring AOP之类的框架。
比如在类加载时直接织入切面逻辑
说一下agent的底层原理
核心机制:Instrumentation API
Java Agent(探针)的底层原理主要基于 JVM 的 Instrumentation API 和 字节码操作技术
通过 类加载机制 实现对 Java 应用的动态监控和修改
Java Agent 的底层能力由 java.lang.instrument
包提供,核心接口为 Instrumentation
void addTransformer(ClassFileTransformer transformer); // 注册字节码转换器
byte[] retransformClasses(Class<?>... classes); // 重新转换已加载的类
作用:允许 Agent 在 类加载时 或 运行时 修改类的字节码
启动时挂载和运行时挂载
a. 启动时挂载(Premain)
原理:通过 JVM 启动参数 -javaagent:agent.jar 指定 Agent。
流程:
- JVM 启动时加载
agent.jar
,调用premain(String args, Instrumentation inst)
方法。 - Agent 注册
ClassFileTransformer
到Instrumentation
实例。 - JVM 加载目标类时,触发
ClassFileTransformer
修改字节码
b. 运行时挂载(Attach)
原理:通过 VirtualMachine.attach(pid)
动态注入 Agent 到已运行的 JVM 进程。
流程:
- 使用
com.sun.tools.attach.VirtualMachine
连接到目标 JVM。 - 调用
loadAgent(agentJarPath)
加载 Agent,触发agentmain(String args, Instrumentation inst)
方法。 - 通过
retransformClasses()
重新转换已加载的类
字节码操作技术
Agent 通过修改类的字节码实现功能增强,常用字节码操作库
类加载拦截流程
JVM 加载类的流程被 Agent 拦截并增强:
- 加载阶段:JVM 读取
.class
文件的字节码。 - 转换阶段:调用注册的
ClassFileTransformer.transform()
方法,修改字节码。 - 定义阶段:JVM 使用修改后的字节码定义类
public class MyTransformer implements ClassFileTransformer {
@Override
public byte[] transform(ClassLoader loader, String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer) {
// 修改 classfileBuffer 并返回新字节码
return enhancedBytecode;
}
}
总结:Java agent 的核心流程
- 注册转换器:通过
Instrumentation
注册ClassFileTransformer
。 - 拦截类加载:JVM 加载类时调用转换器修改字节码。
- 动态增强:在目标方法中插入监控、日志、链路追踪等逻辑。
- 运行时生效:修改后的类被 JVM 直接使用,无需重启应用
agent加载的流程示意图
Premain 模式:
JVM启动 → 加载Agent → 注册Transformer → 拦截类加载 → 修改字节码 → 应用运行
Agentmain 模式:
外部进程Attach → 加载Agent → 注册Transformer → 触发Retransform → 修改已加载类 → 立即生效
面试回答思路引导
Java Agent是JVM启动时或运行时加载的组件,用来修改或增强字节码,从而监控或改变程序的行为
一般在启动或者运行的时候,通过JavaAgent也就是我们探针技术,来修改字节码,来实现增强的业务逻辑
Java Agent 的核心价值在于 无侵入式增强,是 APM、动态调试等工具的关键技术基础,是一种动态技术
常见的agent技术会用在热部署和skywalking链路追踪这些地方
例如热部署我们就是可以在类加载之后替换字节码
例如skywalking链路追踪就是在启动的时候修改字节码,通过探针在服务调用的入口和出口添加跟踪代码,生成和传递TraceID,SpanID等信息,这样可以在分布式系统中追踪请求的路径
一般挂载方式分为两种agent挂载,一种是启动时挂载一种是运行时挂载
启动时挂载是在启动的时候加载需要的jar包到jvm里面并且修改的字节码
运行时挂载是通过动态注入到运行的jvm并加载agent,重新替换已经加载过的类
简单来说,就是在加载类的时候修改我们的字节码进行业务增强,然后让被修改后的类能被JVM直接使用