Java代理工具 one-java-agent

简介: 提供插件化支持,统一管理众多的Java Agent插件支持install/unstall,需要插件方实现接口支持传统的java agent,即已经开发好的java agent

one-java-agent

目标

  1. 提供插件化支持,统一管理众多的Java Agent
  2. 插件支持install/unstall,需要插件方实现接口
  3. 支持传统的java agent,即已经开发好的java agent

插件系统

插件如果希望感知生命周期,可以实现 PluginActivator接口:

public interface PluginActivator {
    // 让插件本身判断是否要启动
    boolean enabled(PluginContext context);
    public void init(PluginContext context) throws Exception;
    /**
     * Before calling this method, the {@link PluginState} is
     * {@link PluginState#STARTING}, after calling, the {@link PluginState} is
     * {@link PluginState#ACTIVE}
     *
     * @param context
     */
    public void start(PluginContext context) throws Exception;
    /**
     * Before calling this method, the {@link PluginState} is
     * {@link PluginState#STOPPING}, after calling, the {@link PluginState} is
     * {@link PluginState#RESOLVED}
     *
     * @param context
     */
    public void stop(PluginContext context) throws Exception;
}

传统的java agent

插件目录下面放一个plugin.properties,并且放上原生的agent jar文件。

例如:

type=traditional
name=demo-agent
version=1.0.0
agentJarPath=demo-agent.jar

则 one java agent会启动这个demo-agent

配置注入

One Java Agent很方便可以注入配置到插件里。

  1. 配置到插件的plugin.properties文件里
  2. 通过-D参数配置,比如插件aaa,则可以配置为-Doneagent.plugin.aaa.key1=value1

然后可以通过PluginContext#getProperty("key1")来获取值。

迁移

  • 从一个传统的Java Agent如何迁移到one java agent的形式?
  • 如何同时支持传统的 -javaagent 方式和 one java agent形式?

比如一个传统的Agent,它会有一个包含 premain 函数的类:

public class MyAgent {
    public static void premain(String args, Instrumentation inst) {
        // do something
    }
}

把上面的Agent做同时支持非常简单,先把原来的初始化逻辑抽取为init函数,把原来的初始化逻辑移到里面:

public class MyAgent {
    public static void premain(String args, Instrumentation inst) {
        init(args, inst);
    }
    public static void init(String args, Instrumentation inst) {
        // do something
    }
}

然后按上面的文档,编写一个MyActivator,在init函数里调用原来的MyAgent.init(args, instrumentation);函数

public class MyActivator implements PluginActivator {
...
    @Override
    public void init(PluginContext context) throws Exception {
        Instrumentation instrumentation = context.getInstrumentation();
        String args = context.getProperty("args");
        MyAgent.init(args, instrumentation);
    }
...
}

在MyActivator init函数里,args可以通过配置注入一节注入,或者通过自定义的方式来获取。

这样子,Agent就可以同时支持传统方式和One Java Agent方式启动。

插件之间类共享

参考fastjson-demo-plugin,它在plugin.properties里配置了exportPackages=com.alibaba.fastjson

当其它插件想引用共享的fastjson时,需要在plugin.properties里配置:

importPackages=com.alibaba.fastjson

插件注册自定义 ClassLoaderHandler

当插件增强应用ClassLoader里加载的类时,会出现一个问题,当调用插件自己的类时,会加载不到。因此提供一个ClassLoaderHandler机制,插件方可以自行注册处理自己package下的类加载。

参考dubbo-test-plugin里:

  • /dubbo-test-plugin/src/main/java/com/test/dubbo/DubboPluginClassLoaderHandler.java
  • /dubbo-test-instrument/src/main/java/org/apache/dubbo/monitor/support/MonitorFilter.java

MonitorFilter里调用了在 plugin里加载的com.test.dubbo.RpcUtils

编译开发

  • 本项目依赖 bytekit: https://github.com/alibaba/bytekit ,可能需要先mvn clean install bytekit
  • 执行测试: mvn clean package -DskipTests && mvn test
  • mvn clean package -P local -DskipTests会打包后安装最新到本地 ~/oneoneagent 目录下
相关文章
|
4天前
|
Arthas Java 测试技术
Java字节码文件、组成,jclasslib插件、阿里arthas工具,Java注解
Java字节码文件、组成、详解、分析;常用工具,jclasslib插件、阿里arthas工具;如何定位线上问题;Java注解
Java字节码文件、组成,jclasslib插件、阿里arthas工具,Java注解
|
21天前
|
缓存 负载均衡 安全
|
18天前
|
XML 存储 JSON
【IO面试题 六】、 除了Java自带的序列化之外,你还了解哪些序列化工具?
除了Java自带的序列化,常见的序列化工具还包括JSON(如jackson、gson、fastjson)、Protobuf、Thrift和Avro,各具特点,适用于不同的应用场景和性能需求。
|
19天前
|
Java 持续交付 项目管理
Maven是一款基于Apache许可的项目管理和构建自动化工具,在Java开发中极为流行。
Maven是一款基于Apache许可的项目管理和构建自动化工具,在Java开发中极为流行。它采用项目对象模型(POM)来描述项目,简化构建流程。Maven提供依赖管理、标准构建生命周期、插件扩展等功能,支持多模块项目及版本控制。在Java Web开发中,Maven能够自动生成项目结构、管理依赖、自动化构建流程并运行多种插件任务,如代码质量检查和单元测试。遵循Maven的最佳实践,结合持续集成工具,可以显著提升开发效率和项目质量。
35 1
|
21天前
|
Java
在Java编程的广阔天地中,条件语句是控制程序流程、实现逻辑判断的重要工具。
在Java编程中,if-else与switch作为核心条件语句,各具特色。if-else以其高度灵活性,适用于复杂逻辑判断,支持多种条件组合;而switch在多分支选择上表现优异,尤其适合处理枚举类型或固定选项集,通过内部跳转表提高执行效率。两者各有千秋:if-else擅长复杂逻辑,switch则在多分支选择中更胜一筹。理解它们的特点并在合适场景下使用,能够编写出更高效、易读的Java代码。
22 1
|
1月前
|
并行计算 Java API
Java中的Lambda表达式:简化代码的现代工具
在Java 8中引入的Lambda表达式,为函数式编程范式铺平了道路,提供了一种更简洁、更灵活的编写匿名方法的方式。本文将深入探讨Lambda表达式如何优化代码结构,提高开发效率,并通过具体示例展示其在实际应用中的魔力。
35 3
|
2月前
|
Java 关系型数据库 MySQL
GraalVM 静态编译下 OTel Java Agent 的自动增强方案与实现
在 2024 OpenTelemetry Community Day 会议中,阿里云可观测工程师张乎兴(望陶)和饶子昊(铖朴)为大家带来了《GraalVM 静态编译下 OTel Java Agent 的自动增强方案与实现》的演讲分享,介绍阿里云在相关领域的探索方案,本文是相关分享对应的中文整理。
222 13
|
15天前
|
数据采集 人工智能 监控
【Azure 应用程序见解】Application Insights Java Agent 3.1.0的使用实验,通过修改单个URL的采样率来减少请求及依赖项的数据采集
【Azure 应用程序见解】Application Insights Java Agent 3.1.0的使用实验,通过修改单个URL的采样率来减少请求及依赖项的数据采集
|
2月前
|
算法 数据可视化 Java
JAVA规则引擎工具有哪些?
本文对比分析了六种Java规则引擎:Drools、IBM ODM (JRules)、Easy Rules、JBPM、OpenL Tablets以及Apache Camel结合规则组件的应用。Drools是一款功能全面的业务规则管理系统,支持DRL文件定义规则、高效的规则匹配算法、复杂的规则流及决策表,并易于与Java应用集成。IBM ODM (原JRules)提供了强大的规则管理功能,包括Web界面和Eclipse插件定义管理规则、直观的决策表和决策树、REST和Java API集成选项及优化的性能。
129 3
|
2月前
|
数据采集 安全 Java
Java Selenium WebDriver:代理设置与图像捕获
Java Selenium WebDriver:代理设置与图像捕获
下一篇
DDNS