https://bigwolftime.github.io/redefine-plugin-with-jvmti/
本文简单介绍下 Java 虚拟机提供的 JVMTI 以及 Instrument, 以及如何利用 Instrument 技术开发一个 jar 插件, 实现代码的动态更新(热部署),
进而提升开发效率.
一. 前言
在日常的开发过程中, 你是否遇到过以下类似场景?
一段代码的执行逻辑不正确, 想排查问题, 但关键的出入参日志没有打印, 想要排查无从下手, 只能在代码中补充上相关日志后, 重新发起编译&部署的流程.
待定位到问题后, 还要再次修改正代码, 重新发起编译&部署. 这样频繁的服务器重启/部署操作不但可能会影响到其他同学的测试与验证, 还会影响开发效率,
假如你的项目比较臃肿, 则大部分的时间都可能花在了代码的编译和服务启动上.
又或者, 一段逻辑执行缓慢, 但不知道哪里的问题, 只能将内部的方法逐一加上执行时长埋点, 加上埋点后又需要经过编译&部署的流程…
甚至是一些低级错误: if 判断写反了, 出现空指针异常, 变量赋值错误等等, 这些都免不了编译和部署.
那么, 有什么方案能在一定程度上简化下上面的流程呢? 这就需要引入 Java 虚拟机提供的一项功能: JVM TI(JVM Tool Interface), 及其对应的实现:
Instrument, 有了它, 不论是代码中加日志, 加埋点, 修复 if 判断, 还是处理空指针异常, 都可以实现快速编译(只编译修改的类)以及热部署.
Instrument 和 JVMTI 分别是什么? 有什么关系吗?
Instrumentation 建立在 JVMTI 基础之上, 利用 JVMTI 提供的 JVM 接口和事件回调, 来实现一套程序探测、分析和修改的框架。
JVMTI 是原生的 Java 虚拟机接口,提供了内部访问、事件通知等底层功能。而 Instrumentation 则在 JVMTI 之上,构建了更丰富的应用程序代理和修改能力。
因此, 两者是协同的关系: JVMTI 提供基础设施, Instrumentation 应用其实现扩展功能.
二. Instrument 功能简介
JVM TI(JVM Tool Interface) 偏向底层, 理解较为晦涩, 便不多介绍, 有兴趣可以看参考部分的链接.
Instrumentation, 即 Java Instrumentation 技术,是 Java 提供的一套程序探测和修改的框架和API。它的主要特征和功能包括:
检测类的加载、卸载事件,也可以代理修改类的定义;
检测方法的调用进入和退出事件,可以收集或修改方法的参数、返回值;
设置断点来控制方法执行路径;
支持定义代理类来包装原有类的功能;
实时计算Java程序的一些度量指标,如运行时间、空间等;
配合 JVMTI 可以访问、监控更丰富的虚拟机运行时信息.
有不少 APM 工具便是依赖了此技术, 例如: SkyWalking, Pinpoint, Elastic APM, BTrace, Arthas 等.
三. 实践
梳理下需求:
以 jar 包的形式打包, 以供其他项目引入;
上传一份源代码, 服务器收到后可以进行动态编译;
编译完成之后, 利用 Instrument 提供的功能, 应用新的字节码;
- 初始化项目
新建一个 maven 项目. 既然要以 jar 形式打包, 那么需要对 pom.xml 进行一些配置:
https://bigwolftime.github.io/redefine-plugin-with-jvmti/
本文简单介绍下 Java 虚拟机提供的 JVMTI 以及 Instrument, 以及如何利用 Instrument 技术开发一个 jar 插件, 实现代码的动态更新(热部署),
进而提升开发效率.
一. 前言
在日常的开发过程中, 你是否遇到过以下类似场景?
一段代码的执行逻辑不正确, 想排查问题, 但关键的出入参日志没有打印, 想要排查无从下手, 只能在代码中补充上相关日志后, 重新发起编译&部署的流程.
待定位到问题后, 还要再次修改正代码, 重新发起编译&部署. 这样频繁的服务器重启/部署操作不但可能会影响到其他同学的测试与验证, 还会影响开发效率,
假如你的项目比较臃肿, 则大部分的时间都可能花在了代码的编译和服务启动上.
又或者, 一段逻辑执行缓慢, 但不知道哪里的问题, 只能将内部的方法逐一加上执行时长埋点, 加上埋点后又需要经过编译&部署的流程…
甚至是一些低级错误: if 判断写反了, 出现空指针异常, 变量赋值错误等等, 这些都免不了编译和部署.
那么, 有什么方案能在一定程度上简化下上面的流程呢? 这就需要引入 Java 虚拟机提供的一项功能: JVM TI(JVM Tool Interface), 及其对应的实现:
Instrument, 有了它, 不论是代码中加日志, 加埋点, 修复 if 判断, 还是处理空指针异常, 都可以实现快速编译(只编译修改的类)以及热部署.
Instrument 和 JVMTI 分别是什么? 有什么关系吗?
因此, 两者是协同的关系: JVMTI 提供基础设施, Instrumentation 应用其实现扩展功能.
二. Instrument 功能简介
JVM TI(JVM Tool Interface) 偏向底层, 理解较为晦涩, 便不多介绍, 有兴趣可以看参考部分的链接.
Instrumentation, 即 Java Instrumentation 技术,是 Java 提供的一套程序探测和修改的框架和API。它的主要特征和功能包括:
检测类的加载、卸载事件,也可以代理修改类的定义;
检测方法的调用进入和退出事件,可以收集或修改方法的参数、返回值;
设置断点来控制方法执行路径;
支持定义代理类来包装原有类的功能;
实时计算Java程序的一些度量指标,如运行时间、空间等;
配合 JVMTI 可以访问、监控更丰富的虚拟机运行时信息.
有不少 APM 工具便是依赖了此技术, 例如: SkyWalking, Pinpoint, Elastic APM, BTrace, Arthas 等.
三. 实践
梳理下需求:
以 jar 包的形式打包, 以供其他项目引入;
上传一份源代码, 服务器收到后可以进行动态编译;
编译完成之后, 利用 Instrument 提供的功能, 应用新的字节码;
新建一个 maven 项目. 既然要以 jar 形式打包, 那么需要对 pom.xml 进行一些配置: