探针的实际使用

最开始接手项目的时候,公司有自己的全链路采集,由于服务端大部分是java项目,所以采集的上报是使用基于拦截的方式(AOP)。

基于拦截其实有比较成功的案例,像pinpoint或者cat。

当时还有基于探针的全链路采集像skywalking,就想着能不能用skywalking的方式(探针)重构下。

重构需要改几百个项目的接入方式,如果没有合适的理由恐怕很难驱动。

于是就想着怎么做一些数据对比,证明探针技术的更有效。

为什么要使用探针技术

其实之前的文章也有写到过,最方便的就是解耦。包含接入和升级都不会有任何的代码侵入,包括java代码或者pom引包。

除此之外呢,我觉得是代码的封闭性。业务不需要关心全链路的采集,甚至看不到任何与之有关的影子,前提是需要做好异常处理和兼容性测试。

当然,数据是少不了的,之前写过一个简略的带数据对比的文章。


归根结底是因为字节码方式不同,性能耗时有区别。

字节码技术介绍

网上有很多的资料可以去看,写的就不那么详细了。

什么是Java字节码,其实就是.class文件。.class文件是由十六进制值组成的,JVM以两个十六进制值为一组,就是以字节为单位进行读取

java 探针接口 java探针技术_java

java 探针接口 java探针技术_java 探针接口_02


JVM加载字节码的过程:

java 探针接口 java探针技术_java 探针接口_03

加载的过程:以JDK 1.8为例

java 探针接口 java探针技术_jvm_04

双亲委托机制:

如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派到父类加载器来完成,每一个层次都是如此,因此最后的加载请求都是传送到最顶层的启动类加载器,只有当父类加载无法加载这个类时(这个类不是自己的加载范围),子加载器才会尝试自己去完成加载。

总结一句话:子类加载器无法加载父类加载器的类。

字节码框架

java 探针接口 java探针技术_java_05

用的比较多的几种框架,asm、javasisst、cglib。

asm

官网:https://asm.ow2.io/index.html

idea插件:ASM Bytecode Outline (https://plugins.jetbrains.com/plugin/5918-asm-bytecode-outline

java 探针接口 java探针技术_jvm_06

javasisit

官网:http://www.javassist.org/http://www.javassist.org/tutorial/tutorial.html

java 探针接口 java探针技术_加载_07

不能操作实例变量和实例方法。

java 探针接口 java探针技术_字节码_08

cglib和jdk proxy

官网:https://github.com/cglib/cglib

最常见的面试题,这俩的区别的优劣势。

java 探针接口 java探针技术_java_09

以一个实际场景来看,分别用这三个框架对一个类的方法进行增强,记录方法调用的耗时。

代码演示:(asm)

java 探针接口 java探针技术_加载_10


代码演示:(javassist)

java 探针接口 java探针技术_加载_11

javaagent 工作原理

JVMTI (jvm interface tool)是 jdk1.2以后加入的,翻译为工具性接口,agentmain和premain,其实就是jvm给开发人员开放了一些api的后门,可以调用一些native的方法。

像我们熟知的idea工具很多地方也是基于探针实现的,启动项目看一下就知道了。

D:\dev\env\jdk\jdk1.8\bin\java.exe -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:63992,suspend=y,server=n -javaagent:C:\Users\烤鸭的世界\AppData\Local\JetBrains\IntelliJIdea2021.2\captureAgent\debugger-agent.jar -Dfile.encoding=UTF-8 -classpath "D:\dev\env\jdk\jdk1.8\jre\lib\xxx.jar" com.maggie.measure.bytecode.javassist.Javassist
JPLISAgent(Java Programming Language Instrumentation Services Agent)

java 探针接口 java探针技术_jvm_12


java 探针接口 java探针技术_java_13


java 探针接口 java探针技术_java 探针接口_14


java 探针接口 java探针技术_加载_15