Instrumentation简介
Java探针技术,通过Instrumentation
,开发者可以构建一个独立于应用程序的代理程序(Agent),用来监测和协助运行在JVM上的程序,甚至能够替换和修改某些类的定义而对业务代码没有侵入
成熟应用
java领域的APM(Application Performance Management应用性能管理)工具,几乎都是基于Instrumentation实现的。
- zipkin:Twitter公司开源的一个分布式追踪工具,被Spring Cloud Sleuth集成,使用广泛而稳定
- skywalking:中国人吴晟(华为)开源的一款分布式追踪,分析,告警的工具,现在是Apache旗下开源项目
- cat:大众点评开源的一款分布式链路追踪工具。
Arthas
是Alibaba开源的Java诊断工具也是基于此。
这么多优秀的产品都在使用java探针Instrumentation
,是不是有兴趣深入了解一下呢。
使用流程
入口代理类
在main方法前执行
1 | java复制代码public class MyAgent { |
需要提供一下两个方法之一,如果两个的话,前一个优先级较高
1 | arduino复制代码public static void premain(String agentOps, Instrumentation instrumentation); |
自定义ClassFileTransformer
1 | java复制代码package top.soft1010.java.myagent; |
ClassFileTransformer用于修改class文件,该操作发生在 JVM 加载 class 之前。它只有一个transform
方法,实现该方法可以修改 class字节码(这里可以使用javassist,asm等),并返回修改后的 class字节码,有两点要注意:
- 如果此方法返回null, 表示我们不对类进行处理直接返回。否则,会用我们返回的byte[]来代替原来的类
- ClassFileTransformer必须添加进Instrumentation才能生效 Instrumentation#addTransformer(ClassFileTransformer)
- 当存在多个Transformer时,一个Transformer调用返回的byte数组将成为下一个Transformer调用的输入
运行
这里我们直接写一个main方法类,当然也可以是jar
1 | typescript复制代码public class MyTest { |
执行命令
1 | 复制代码java -javaagent:myagent.jar top.soft1010.java.myagent.MyTest |
面试
1、加载类的时候,对字节码进行修改?
1 | css复制代码能,使用java探针,javaagent就可以。 |
2、说说java探针技术javaagent的应用
1 | bash复制代码skywalking:中国人吴晟(华为)开源的一款分布式追踪,分析,告警的工具,现在是Apache旗下开源项目 |
源码
文中涉及到的代码
源码
本文转载自: 掘金