服务监控原理-Agent探针

这是我参与更文挑战的第26天,活动详情查看: 更文挑战

什么是java agent(探针)

Java agent是在JDK1.5引入的,是一种可以动态修改Java字节码的技术。java类编译之后形成字节码被JVM执行,JVM在执行这些字节码之前获取这些字节码信息,并且对这些字节码进行修改,来完成一些额外的功能,这种就是java agent技术。

原理

1,java agent能够在加载java字节码之前进行拦截并对字节码进行修改
2,在jvm运行期间修改已经加载的字节码

通过以上两种就可以实现在一些框架或是技术的采集点进行字节码修改,可以对应用进行监控,或是对执行指定方法或是接口时额外添加操作(打印日志、打印方法执行时间、采集方法的入参和结果等)

实现

java agent实现字节码增强到过程大概是:
1.修改字节码
2.加载新到字节码
3.替换旧的字节码

第二步可以通过自定义ClassLoader来加载修改的字节码,第三步可以通过JVM加载或运行字节码时进行替换,那么第一步修改字节码该如何进行呢,至少大部分人时不会修改的,那么就需要使用工具来修改。

技术框架

  • JVMTI
  1. JVMTI是JVM Tool Interface的缩写,是JVM暴露出来给用户扩展使用的接口集合,JVMTI是基于事件驱动的,JVM每执行一定的逻辑就会调用一些事件的回调接口,这些接口可以给用户自行扩展来实现自己的逻辑
  • JVMTIAgent
  1. JVMTIAgent是一个动态库,利用JVMTI暴露出来的接口实现用户自行的逻辑(eclipse、idea等工具等代码调试就是通过这个实现的)
  • JVMTIAgent主要有三个方法,
  1. Agent_OnLoad方法,如果agent在启动时加载,就执行这个方法

Agent_OnAttach方法,如果agent不是在启动的时候加载的,是我们先attach到目标线程上,然后对对应的目标进程发送load命令来加载agent,在加载过程中调用Agent_OnAttach函数
Agent_OnUnload方法,在agent做卸载掉时候调用

  • instrument agent
  1. instrument agent实现了Agent_OnLoad方法和Agent_OnAttach方法,也就是即能在启动的时候加载agent,也可以在运行期来加动态加载agent,运行期动态加载agent依赖JVM的attach机制实现,通过发送load命令来加载agent
  • JVM Attach机制
  1. jvm attach机制上JVM提供的一种JVM进程间通信的功能,能让一个进程传命令给另一个进程,并进行一些内部的操作,比如进行线程dump,那么就需要执行jstack进行,然后把pid等参数传递给需要dump的线程来执行,这就是一种java attach。
  • Class Transform的实现
  1. 第一次类加载的时候要求被transform的场景,在加载类文件的时候发出ClassFileLoad事件,交给instrument agent来调用java agent里注册的ClassFileTransformer实现字节码的修改
  • Class Redefind的实现
  1. 类重新定义,主要用在已经被加载的类上

基于javaAgent和Java字节码注入技术的java探针工具技术原理

333

JDK5中只能通过命令行参数在启动JVM时指定javaagent参数来设置代理类,而JDK6中已经不仅限于在启动JVM时通过配置参数来设置代理类,JDK6中通过 Java Tool API 中的 attach 方式,我们也可以很方便地在运行过程中动态地设置加载代理类,以达到 instrumentation 的目的。Instrumentation 的最大作用,就是类定义动态改变和操作。最简单的一个例子,计算某个方法执行需要的时间,不修改源代码的方式,使用Instrumentation 代理来实现这个功能,给力的说,这种方式相当于在JVM级别做了AOP支持,这样我们可以在不修改应用程序的基础上就做到了AOP。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享