共计 2279 个字符,预计需要花费 6 分钟才能阅读完成。
UAVStack 的中间件增强框架专题(MOF)】为大家详细讲述 UAV 中的 MOF Agent 是如何借助 javaagent(premain)和 javaassist 技术在对应用无侵入的前提下完成数据捕获的。欢迎继续关注 UAVStack,了解 UAV 更多的技术创新。
前言
MOF(Moniter Framwork)作为 UAV 应用数据捕获框架,不但实现了对应用无侵入的数据捕获,而且在框架层面实现了功能的灵活控制,并且保证了良好的可扩展性,在 UAV 中具有举足轻重的地位。
MOF Agent 注入机制作为 UAV MOF 工作的基础,也为 UAV 无侵入捕获应用数据提供可能。UAV Agent 代码注入机制结合 javaagent(premain)和 javaassist 技术,在应用字节码加载到 JVM 之前进行字节码改写。通过适配器适配(adaptor)不同应用服务器,目前支持的包括 Tomcat(6+)、SpringBoot、Jetty(7+)等,结合拦截器(interceptor)实现对不同应用服务器切点,为 MOF 框架和应用数据捕获提供基础。
Java Agent 技术
自 JDK1.5 开始, JDK 中引入了 java.lang.Instrument 包,提供在 Java 程序类加载之前修改 class 字节码和运行时动态修改系统中 Class 类型的能力,其中一个核心概念即 Java Agent,可以理解为一个字节码转换器或者 Class 对象转换器。针对字节码转化和 Class 对象转化,Java agent 分别提供了相应的方式,即 Java agent premain 方式和 Java agent agentmain 方式。UAV MOF 使用的是 Java agent premain 方式,因此本文主要讲解该转化方式。
Java agent premain 方式提供了在字节码 class 文件被 JVM 加载之前拦截并修改的神奇能力,目前基本所有基于探针的监控系统(如 ONEAPM Servers)都是基于这种能力实现的对应用的无侵入监控。Java agent premain 中有两个重要的概念,分别是 premain 和 transformer。
premain 将在程序的 main 方法之前执行,我们知道程序的入口是 main 方法,premain 代表了在程序正式启动之前执行的动作,具备类似 AOP 的能力。transformer,寓意转化器,提供字节码文件流转化的能力。
图 1 Class 文件转化图
集合 premain 和 transformer 两大神器,可以对加载进 JVM 的任意 Class 文件进行修改。其流程如图 1 所示,任何 Class 文件加载时候,都要经过 premain 这一关卡,通过一系列的 transformer,Class 字节码文件流最终变成那个完美的它,然后被加载到 JVM 中。当然,修改 Class 字节码文件流的动作是在 transformer 中进行的。这就有个问题,拿到了字节码文件流,怎么修改呢?当然是发挥人类的特长,借助工具,比如说 javassist。
Javassist 技术
Javaassist 是一个开源的分析、编辑和创建 Java 字节码的类库,能运行时动态生成类,修改类,并且能直接使用 java 编码。
前文 Java agent 技术中,在 transformer 中拿到了类的字节码文件流,利用 Javaassist 解析字节码流为类对象,并对其进行修改,非常快速便捷。Javassist 与 Java agent 结合将事半功倍。关于 Javaassist 的使用还请参考官网 http://www.javassist.org。
MOF Agent 注入机制
前文中介绍了一对好伙伴:Javaagent 技术和 Javassit 技术。Java agent 负责拦截和转换字节码流,转换的过程中使用 Javaassist 进行解析和修改。此两者技术为 MOF Agent 注入机制提供了技术基础。相信小伙伴对 MOF Agent 注入机制已经有了一定了猜想。
图 2 为 MOF Agent 的组件图,MOFAgent 基于 java agent premain 技术实现,拦截所有加载的 Class 字节码文件流;并通过 UAV 的 transformer(MOFClsTransformer)进行字节码劫持和转化。UAV 做的不仅仅是这些,还能自动感知不同应用服务器,并对不同应用服务器生命周期中的重要位置注入切点。UAV 通过适配器(Adaptor)进行不同应用服务适配,通过拦截器(interceptor)进行具体的切点注入实现。
图 2 MOF Agent 组件图
MOFAgent 注入机制将对应用服务器生命周期中关键位置注入切点,为 MOF 框架初始化、应用的画像信息和实时监控数据信息捕获提供基础。MOF Agent 注入的不同切点会产生不同的事件,通过事件驱动后续 MOF 框架。MOF 支持的主要切点如下:
应用服务器入口
应用服务器入口切点,UAV 将完成 MOF Jar 包加载和配置文件初始化;
应用服务器启动
应用服务器启动时,切将保证 UAV MOF 将随应用服务器启动完成 MOF 内部代码的自启动和初始化;
应用服务器请求处理和回复
应用服务器请求和回复切点,是 UAV 对应用实时监控数据捕获的重要切点,监控应用服务器,应用,所有的 URL 的性能指标;
应用初始化
应用初始化切点时,UAV 将对应用的 Filter 进行改写,支持 MOF 的 Global Filter 机制;同时完成对应用画像信息进行捕获等;
应用停止
应用停止时切点,UAV 将完成 MOF 相关机制的停止等操作
本文主要目的是让读者了解 UAV MOF Agent 代码注入机制原理和相关实现。MOF 中其它重要框架及其实现原理将会在后续文章中依次剖析,敬请期待。