当前位置:   article > 正文

java agent设计开发概要_javaagent 开发

javaagent 开发

agent开发设计

agent 开发的一些心得,适合熟悉agent或者有agent开发需求的同学

1 有个基础的agent,是java 标准的agent。这是agent代码入口

2 设计包结构
基础agent
agent下有plugin,加载plugin可以自己定义一个类加载器

plugin:插件定义具体的模块功能module,module是要加入到业务的类加载器中,因为是和业务相关的具体功能

module: 具体对业务增强的jar包

conf: 一些配置文件

在这里插入图片描述

3 设计类加载机制
plugin 有独立的Plugin加载器,加载plugin定义

module 会被添加到系统类加载器或者bootstrap加载器中

spring boot的项目需要对JarLauncher进行字节码增强

bootstrap层module: 将module jar放入bootstrap层类加载器完成字节码增强,具体的业务功能放到系统类加载器。
也就是有2个module,一个bootstrap层的字节码增强module,一个是具体业务的系统类加载器层module。bootstrap层module通过类加载器去加载系统类加载器层的业务module

类加载机制架构图
在这里插入图片描述

4 module 功能扩展手段
4.1. 通过spi扩展机制,像spring boot dubbo都有spi扩展机制

4.2. 将开源的jar包通过类加载机制添加到业务类加载器中,相当于无侵入帮助用户完成pom文件依赖。如果代码不满足需求,可以修改源码后,在将修改后的jar加载到类加载器

4.3. 使用字节码增强工具进行字节码增强

5 独立日志设计
要有自己的独立日志打印,最好不要用log4j logback这类框架,因为可能和业务的日志打印出现冲突。

可以使用java.util.logging.Logger ,但是只能打印到控制台日志,和业务日志混合在一起了。

6 依赖包独立
agent内部依赖的公共工具包,需要通过maven-shade-plugin 插件进行打包,这样避免业务和agent使用了同一个包的不同版本,导致冲突

代码上能不依赖外部包就不依赖外部。

7 版本适配
agent作为一个公共的agent,使用agent的业务系统可能有很多不同的版本。适配的module jar也是有所不同的。
这里需要在plugin里对业务所使用的版本(dubbo/spring boot等)做个判断,根据不同的版本依赖不同的module jar

判断业务使用框架的版本: 像dubbo spring boot都有对应的Version类,如果没有Version类的,可以通过判断某个版本有某个类来判断。

8 字节码增强工具选择

asm :成熟的开源框架

bytekit:arthas内部使用的字节码工具,可以支持注解使用,屏蔽了字节码操作细节。首选

在进行字节码增强时,可以将业务逻辑直接植入字节码。也可以字节码增强去调用另外的静态方法,在静态方法里面做具体业务逻辑。

9 字节码增强延时机制设计

addTransformer(transformer,false)。只有在类首次加载时,才会触发transform进行字节码增强

addTransformer(transformer,true)。可以通过inst.retransformClasses进行再次增强,再次增强也是有限制,增强的类不能有对类基本结构(增加/修改/删除字段或方法,方法返回值不能被修改),否则增强失败。

可以在一定时间(保证业务启动成功后),调用retransformClasses 进行二次增强,用以避免增强前类就已经被加载过了。

10 热加载/卸载

字节码增强的功能: 可以通过retransformClasses 二次增强,进行热加载。redefineClasses 可以重新定义类字节码,可以把原始字节码重新加载。重新定义类不能有对类基本结构(增加/修改/删除字段或方法,方法返回值不能被修改),否则失败。

spi 扩展的功能: 没法进行热加载和协助,因为这部分是由应用启动的时候进行加载的。可以加开关,将开关配置下发来动态控制功能是否生效


采坑:

  1. agent使用的第三方公共包和业务使用的第三方公共包有版本冲突,使用maven-shade-plugin 解决

  2. 有时候日志打印不出来,因为agent使用的日志包和业务的有冲突

  3. 和定时任务saturn框架有冲突。因为saturn框架是采用独立lib加载的方式,在对saturn lib下的类进行字节码增强后,saturn lib下的类没有办法找到在系统类加载器的agent 类。典型案例就是skywalking agent

  4. agent增强某个类,这个类已经被加载过了,增强就不生效了。多个agent对同个类进行增强时,经常有这个问题

  5. 有个节点偶发性出现jvm异常导致pod重启,重启1-2次后正常
    agent 的增强和jfr机制在并发下有bug
    加入io.lettuce.core.jfr=false 解决
    参考:
    jdk jfr bug:https://bugs.openjdk.org/browse/JDK-8249009
    lettuce jfr: https://github.com/lettuce-io/lettuce-core/wiki/Connection-Events

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号