Agent启动介绍

javaagent是一种插件机制,通过JVMTI和Instrumentation接口实现对目标代码的修改。它可以预处理字节码、运行时变更已加载类,以及管理类加载。文章介绍了如何实现agent的启动方法,如premain和agentmain,以及MANIFEST.MF的作用。ByteBuddy工具用于便捷创建JavaAgent,实现AOP和非侵入式数据埋点。
摘要由CSDN通过智能技术生成

java agent介绍

java agent本质上可以理解为一个插件,该插件就是一个精心提供的jar包,这个jar包通过JVMTI(JVM ToolInterface)完成加载,最终借助JPLISAgent(JavaProgramming Language Instrumentation Services Agent)完成对目标代码的修改。

java agent技术的主要功能如下:

  • 可以在加载java文件之前做拦截把字节码做修改

  • 可以在运行期将已经加载的类的字节码做变更

  • 还有其他的一些小众的功能

  • 获取所有已经被加载过的类

  • 获取所有已经被初始化过了的类

  • 获取某个对象的大小

  • 将某个jar加入到bootstrapclasspath里作为高优先级被bootstrapClassloader加载

  • 将某个jar加入到classpath里供AppClassloard去加载

  • 设置某些native方法的前缀,主要在查找native方法的时候做规则匹配

java Instrumentation API

实现agent启动方法

Java Agent支持目标JVM启动时加载,也支持在目标JVM运行时加载,这两种不同的加载模式会使用不同的入口函数,如果需要在目标JVM启动的同时加载Agent,那么可以选择实现下面的方法:

public static void premain(String agentArgs, Instrumentation inst);

public static void premain(String agentArgs);

如果希望在目标JVM运行时加载Agent,则需要实现下面的方法:

public static void agentmain(String agentArgs, Instrumentation inst);

public static void agentmain(String agentArgs);

这两组方法的第一个参数AgentArgs是随同“–javaagent”一起传入的程序参数,如果这个字符串代表了多个参数,就需要自己解析这些参数。inst是Instrumentation类型的对象,是JVM自动传入的,我们可以拿这个参数进行类增强等操作。

MANIFEST.MF 作用

If you remove META-INF from a jar then there is no MANIFEST.MFand so java -jar can't find the main class.

Agent需要打包成一个jar包,在ManiFest属性中指定“Premain-Class”或者“Agent-Class”,且需根据需求定义Can-Redefine-Classes和Can-Retransform-Classes:

Manifest-Version: 1.0

Implementation-Title: apm-agent

Implementation-Version: 6.6.0

Built-By: wusheng

Specification-Vendor: The Apache Software Foundation

Can-Redefine-Classes: true

Specification-Title: apm-agent

Implementation-Vendor-Id: org.apache.skywalking

Implementation-Vendor: The Apache Software Foundation

Premain-Class: org.apache.skywalking.apm.agent.SkyWalkingAgent

Can-Retransform-Classes: true

Created-By: Apache Maven 3.6.1

Build-Jdk: 1.8.0_232

Specification-Version: 6.6

Implementation-URL: http://maven.apache.org

启动时修改

启动时修改主要是在jvm启动时,执行native函数的Agent_OnLoad方法,在方法执行时,执行如下步骤:

  • 创建InstrumentationImpl对象

  • 监听ClassFileLoadHook事件

  • 调用InstrumentationImpl的loadClassAndCallPremain方法,在这个方法里会去调用javaagent里MANIFEST.MF里指定的Premain-Class类的premain方法

运行时修改

运行时修改主要是通过jvm的attach机制来请求目标jvm加载对应的agent,执行native函数的Agent_OnAttach方法,在方法执行时,执行如下步骤:

  • 创建InstrumentationImpl对象

  • 监听ClassFileLoadHook事件

  • 调用InstrumentationImpl的loadClassAndCallAgentmain方法,在这个方法里会去调用javaagent里MANIFEST.MF里指定的Agentmain-Class类的agentmain方法

agent通过 org.apache.skywalking.apm.agent.core.boot.BootService 实现了整体的插件化,agent启动会加载所有的BootService实现,并通过 ServiceManager 来管理这些插件的生命周期,采集jvm指标、gRPC连接管理、调用链数据维护、数据上报OAP这些服务均是通过这种方式扩展。

然后,agent还通过bytebuddy以javaagent的模式,通过字节码增强的机制来构造AOP环境,再提供PluginDefine的规范方便探针的开发,最终实现非侵入性的数据埋点,采集调用链数据。

参考链接:

Instrumentation 新功能

https://www.ibm.com/developerworks/cn/java/j-lo-jse61/index.html

JVM 源码分析之javaagent 原理完全解读

https://www.infoq.cn/article/javaagent-illustrated/

破解 Java Agent 探针黑科技!

https://xie.infoq.cn/article/a6012a49401802c963d416970

通过使用 Byte Buddy,便捷地创建 Java Agent

https://www.infoq.cn/article/Easily-Create-Java-Agents-with-ByteBuddy

最全面!一文让你看懂无侵入的微服务探针原理

https://www.infoq.cn/article/q1ivDiHCAFwKYF8Zmyj5

从 0-1 开发 Java 性能剖析工具

https://www.infoq.cn/article/esVkcjQPTh3YzDFUCUKd

虚拟机技术

https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html

vivo 调用链Agent 原理及实践

https://xie.infoq.cn/article/c98b32ef8bf0193e4bc40be70

ASM

https://asm.ow2.io/faq.html

Byte Buddy 教程

https://notes.diguage.com/byte-buddy-tutorial/

JVMTI(JVMTool Interface)

https://docs.oracle.com/en/java/javase/16/docs/specs/jvmti.html

流概念

https://ci.apache.org/projects/flink/flink-docs-release-1.11/concepts/index.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

microsoft_love

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值