再写java探针

大家好,我是烤鸭:
    以前写过一篇全链路探针实现的文章,最近同事间搞技术分享,再整理一篇。可惜这两年没有继续搞这方面的技术,算是两年前的拓展篇吧。很多技术只放了图,文字就不写了,可以参考下边的拓展阅读。

文中显示代码的地址:https://gitee.com/fireduck_admin/link-trace-demo

探针的实际使用

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

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

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

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

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

为什么要使用探针技术

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

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

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

https://blog.csdn.net/Angry_Mills/article/details/107868420

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

字节码技术介绍

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

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

在这里插入图片描述
JVM加载字节码的过程:
在这里插入图片描述

加载的过程:以JDK 1.8为例

在这里插入图片描述

双亲委托机制:

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

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

字节码框架

在这里插入图片描述

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

asm

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

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

在这里插入图片描述

javasisit

官网:http://www.javassist.org/http://www.javassist.org/tutorial/tutorial.html
在这里插入图片描述

不能操作实例变量和实例方法。
在这里插入图片描述

cglib和jdk proxy

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

最常见的面试题,这俩的区别的优劣势。
在这里插入图片描述

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

代码演示:(asm)
在这里插入图片描述
代码演示:(javassist)

在这里插入图片描述

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)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

拓展阅读

class文件官方说明

彻底让你搞懂什么是Java字节码

jvm 加载字节码过程

使用ASM操作Java字节码,实现AOP原理

美团-Java字节码增强探秘

NoClassDefFoundError排查

JPDA学习

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烤鸭的世界我们不懂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值