ByteBuddy

介绍

  • 是一个字节码生成和操作库
  • 用于 在Java应用程序运行时 创建和修改Java类,而无需编译器的帮助。
  • 允许创建任意类,并且不限于实现用于创建运行时代理的接口。
  • 提供了一种API

可以使用Java代理或在构建过程中手动更改类,很容易操作字节码,控制类和方法

用于定义所谓的 Java 代理,该代理允许在任何 Java应用程序的运行期间 进行代码转换。

  • 不仅限于创建子类和操作类,还可以转换现有代码。

Byte Buddy优势

  1. 无需理解字节码指令,即可使用简单的 API,就能很容易操作字节码,控制类和方法。
  2. 支持Java 11
  3. 库轻量,仅取决于Java字节代码解析器库ASM的访问者API,它本身不需要任何其他依赖项。
  4. 性能超过以下项
    1. JDK动态代理
    2. cglib
    3. Javassist

能够生成代码库的方法

  1. Java Proxy
  2. CGLIB
  3. Javassist
  4. Byte Buddy

2.1、Java Proxy

是 JDK 自带的一个代理工具,它允许为实现了一系列接口的类生成代理类。

要求目标类必须实现接口是一个非常大限制,例如,在某些场景中,目标类没有实现任何接口且无法修改目标类的代码实现,Java Proxy 就无法对其进行扩展和增强了。

2.2、CGLIB

是一个相当强大的库

非常 复杂

许多用户放弃了 CGLIB

2.3、Javassist

对 Java开发者 来说非常友好

使用 Java源代码字符串 和 Javassist 提供的一些简单 API ,共同拼凑出用户想要的 Java类

Javassist 自带一个编译器,拼凑好的 Java 类在程序运行时会被编译成为字节码并加载到 JVM 中。

Javassist 库简单易用,而且使用 Java 语法构建类与平时写 Java 代码类似

Javassist编译器 在性能上比不了 Javac编译器,而且在动态组合字符串以实现比较复杂的逻辑时容易出错。

2.4、Byte Buddy

提供了一种非常灵活且强大的领域特定语言,通过编写简单的 Java 代码即可创建自定义的运行时类。

具有非常开放的定制性,能够应付不同复杂度的需求。

简单使用

java--字节码增强--1.3--ByteBuddy--ByteBuddy常用注解_bytebuddy教程-CSDN博客

字节码增强-agent

介绍

笼统地来讲,Java Agent 是一个统称,该功能是 Java虚拟机 提供的一整套后门,通过这套后门可以对虚拟机方方面面进行监控与分析,甚至干预虚拟机的运行。

Java Agent 又叫做 Java探针,是一种可以动态修改 Java字节码的技术。

Java类 编译之后形成字节码被 JVM 执行,在 JVM 在执行这些字节码之前获取这些字节码信息,并且通过字节码转换器对这些字节码进行修改,来完成一些额外的功能。

Instrumentation工具包

  • 名称:java.lang.instrument
  • 借助该包,开发者可以构建一个独立于应用程序的代理(Agent),用来 监测和协助 运行在 JVM上的程序,甚至能够动态替换和修改某些类的定义。这样的特性实际上提供了一种虚拟机级别的AOP实现。
  • java.lang.instrument 是基于JVMTI机制实现的

JVMTI机制

JVMTI:Java Virtual Machine Tool Interface

是一套由 Java 虚拟机提供的了一套代理程序机制,可以支持第三方工具程序 以代理的方式 连接和访问 JVM。

功能丰富,包括虚拟机中线程、内存/堆/栈,类/方法/变量,事件/定时器处理等等。

使用 JVMTI 一个基本的方式就是设置回调函数,在某些事件发生的时候触发并作出相应的动作,这些事件包括虚拟机初始化、开始运行、结束,类的加载,方法出入,线程始末等等。

其他使用 Agent技术 的开源项目

Arthas(阿里,开源)

Java诊断工具。

在线排查问题,无需重启

动态跟踪 Java 代码

实时监控 JVM 状态。

JVM SandBox(阿里,开源)

实时、无侵入、动态可插拔的字节码增强框架

用于线上故障定位、系统流控、动态日志等场景

Skywalking(开源)

针对服务的调用链路、JVM 基础监控信息进行采集。

jvm-profiler(Uber,开源)

通过 Java Agent 采集 JVM CPU、Memory、IO等指标并发送给 Kafka、Console 以及可以自定义的发送器。

BTrace(sun,开源)

一款java 动态、安全追踪工具

可以不停机的情况下监控线上情况

做到最少的侵入,占用最少的系统资源。

OpenTracing数据模型

https://github.com/opentracing-contrib/opentracing-specification-zh/blob/master/specification.md#opentracing%E6%95%B0%E6%8D%AE%E6%A8%A1%E5%9E%8B

trace:一次调用链,包含多个span

span:跨度,可以理解为一次埋点,可以是一次方法调用, 一个程序块的调用, 或者一次RPC/数据库访问.只要是一个具有完整时间周期的程序访问,都可以被认为是一个span。

Span

包含属性

属性

含义

An operation name

操作名称

A start timestamp

起始时间

A finish timestamp

结束时间

Span Tag

一组键值对构成的Span标签集合。键值对中,键必须为string,值可以是字符串,布尔,或者数字类型

Span Log

一组span的日志集合。 每次log操作包含一个键值对,以及一个时间戳。 键值对中,键必须为string,值可以是任意类型

SpanContext

Span上下文对象

当前调用链状态

Baggage Items

Trace的随行数据,是一个键值对集合,它存在于trace中,也需要跨进程边界传输

References

相关的零个或者多个Span(Span间通过SpanContext建立这种关系)

Span之间的关系

两种:childOf(父子) FollowsFrom(跟随)

父子

一个span可能是一个父级span的孩子,即"ChildOf"关系。在"ChildOf"引用关系下,父级span某种程度上取决于子span。下面这些情况会构成"ChildOf"关系:

  • 一个RPC调用的服务端的span,和RPC服务客户端的span构成ChildOf关系
  • 一个sql insert操作的span,和ORM的save方法的span构成ChildOf关系
  • 很多span可以并行工作(或者分布式工作)都可能是一个父级的span的子项,他会合并所有子span的执行结果,并在指定期限内返回
    [-Parent Span---------]
         [-Child Span----]

    [-Parent Span--------------]
         [-Child Span A----]
          [-Child Span B----]
        [-Child Span C----]
         [-Child Span D---------------]
         [-Child Span E----]

跟随

一些父级节点不以任何方式依赖他们子节点的执行结果,这种情况下,我们说这些子span和父span之间是"FollowsFrom"的因果关系。可以理解为异步执行

    [-Parent Span-]  [-Child Span-]


    [-Parent Span--]
     [-Child Span-]


    [-Parent Span-]
                [-Child Span-]

SkyWalking

SkyWalking 源码分析| ProcessOn免费在线作图,在线流程图,在线思维导图

pfinder:

pfinder实现原理揭秘 - 京东云开发者 - 博客园

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐