hz90 / java-base-knowledge

0 stars 0 forks source link

java探针 #2

Open hz90 opened 5 years ago

hz90 commented 5 years ago

java agent(java 探针) 一种动态修改java字节码的技术,java类编译之后形成字节码后被JVM执行,JVM在执行这些字节码之前获取这些字节码信息,并且对这些字节码进行修改,来完成一些额外的功能。

1.java agent能够在加载java字节码之前进行拦截并对字节码进行修改 2.在jvm运行期间修改已经加载的字节码 通过以上两种就可以实现在一些框架或是技术的采集点进行字节码修改,可以对应用进行监控,或是对执行指定方法或是接口时额外添加操作(打印日志、打印方法执行时间、采集方法的入参和结果等)

java agent的实现原理? JVMTI JVMTI是JVM Tool Interface的缩写,是JVM暴露出来给用户扩展使用的接口集合,JVMTI是基于事件驱动的,JVM每执行一定的逻辑就会调用一些事件的回调接口,这些接口可以给用户自行扩展来实现自己的逻辑 JVMTIAgent JVMTIAgent是一个动态库,利用JVMTI暴露出来的接口实现用户自行的逻辑(eclipse、idea等工具等代码调试就是通过这个实现的) JVMTIAgent主要有三个方法, Agent_OnLoad方法,如果agent在启动时加载,就执行这个方法 Agent_OnAttach方法,如果agent不是在启动的时候加载的,是我们先attach到目标线程上,然后对对应的目标进程发送load命令来加载agent,在加载过程中调用Agent_OnAttach函数 Agent_OnUnload方法,在agent做卸载掉时候调用 instrument agent instrument agent实现了Agent_OnLoad方法和Agent_OnAttach方法,也就是即能在启动的时候加载agent,也可以在运行期来加动态加载agent,运行期动态加载agent依赖JVM的attach机制实现,通过发送load命令来加载agent JVM Attach机制 jvm attach机制上JVM提供的一种JVM进程间通信的功能,能让一个进程传命令给另一个进程,并进行一些内部的操作,比如进行线程dump,那么就需要执行jstack进行,然后把pid等参数传递给需要dump的线程来执行,这就是一种java attach。 Class Transform的实现 第一次类加载的时候要求被transform的场景,在加载类文件的时候发出ClassFileLoad事件,交给instrument agent来调用java agent里注册的ClassFileTransformer实现字节码的修改 Class Redefind的实现 实现字节码增强的技术框架有哪些? 类重新定义,主要用在已经被加载的类上 原理了解清楚了就需要实现,java agent实现字节码增强到过程大概是: 1.修改字节码、2.加载新到字节码、3.替换旧的字节码 第二步可以通过自定义ClassLoader来加载修改的字节码,第三步可以通过JVM加载或运行字节码时进行替换,那么第一步修改字节码该如何进行呢,至少大部分人时不会修改的,那么就需要使用工具来修改, 目前实现修改字节码的工具主要有ASM、Javassist和byte buddy

参考:https://www.wandouip.com/t5i189965/

字节码技术: java程序通过javac编译成class,class就是字节码文件,正是由于字节码,scala,groovy可以在jvm上运行, 开发框架、监控系统、中间件、语言字节码技术都是必杀技

字节码框架(ASM/Javassist) ASM 速度快、代码量小、功能强大 要写字节码、学习曲线高 Javassist 学习简单,不用写字节码 比ASM慢,功能少

Java Instrumentation介绍 指的是可以用独立于应用程序之外的代理(agent)程序,agent程序通过增强字节码动态修改或者新增类,利用这样特性可以设计出更通用的监控、框架、中间件程序 在JVM启动参数加–javaagent:agent_jar_path/agent.jar即可运行(在JDK5及其后续版本才可以) Instrumentation 是javaagent的实现机制,原理是Instrumentation实现了jvm指令load指令