字节码Agent
笼统地来讲,Java Agent 是一个统称,该功能是 Java虚拟机 提供的一整套后门,通过这套后门可以对虚拟机方方面面进行监控与分析,甚至干预虚拟机的运行。Java Agent 又叫做 Java探针,是一种可以动态修改 Java字节码的技术。Java类 编译之后形成字节码被 JVM 执行,在 JVM 在执行这些字节码之前获取这些字节码信息,并且通过字节码转换器对这些字节码进行修改,来完成一些额
ByteBuddy
介绍
- 是一个字节码生成和操作库
- 用于 在Java应用程序运行时 创建和修改Java类,而无需编译器的帮助。
- 允许创建任意类,并且不限于实现用于创建运行时代理的接口。
- 提供了一种API
可以使用Java代理或在构建过程中手动更改类,很容易操作字节码,控制类和方法
用于定义所谓的 Java 代理,该代理允许在任何 Java应用程序的运行期间 进行代码转换。
- 不仅限于创建子类和操作类,还可以转换现有代码。
Byte Buddy优势
- 无需理解字节码指令,即可使用简单的 API,就能很容易操作字节码,控制类和方法。
- 支持Java 11
- 库轻量,仅取决于Java字节代码解析器库ASM的访问者API,它本身不需要任何其他依赖项。
- 性能超过以下项
- JDK动态代理
- cglib
- Javassist
能够生成代码库的方法
- Java Proxy
- CGLIB
- Javassist
- 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数据模型
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上下文对象
|
||||||||||||
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:
更多推荐
所有评论(0)