Java-Agent 原理-统计方法调用时间 | 学习笔记

简介: 快速学习 Java-Agent 原理-统计方法调用时间

开发者学堂课程【分布式链路追踪 SkywalkingJava-Agent 原理-统计方法调用时间】学习笔记,与课程紧密连接,让用户快速学习知识。

课程地址https://developer.aliyun.com/learning/course/743/detail/13166


Java-Agent 原理-统计方法调用时间


Java-Agent 原理-统计方法调用时间

上节课学习了 Java-Agent-环境搭建,这节课学习Skywaiking 如何对方法调用时间进行统计。

Skywaiking 利用 Java agent 和 ByteBuddy 技术来统计方法的调用时长,但Java agent无法统计方法内的调用时间,所以需要学习新的框架,ByteBuddy。

Bytebuddy 是开源的、基于 Apache2.0 许可证的库,主要目的是解决字节码操作和 instumentation API 的复杂性。对于一些字节码增强的代码操作变得更简单。

之前对方法调用时间进行统计是利用的 Spring 的 AUG 技术但现在的探针并没有集成 Spring 的框架所以无法利用该技术完成操作,因此要利用字节码对其增强,增强过后通过拦截器拦截达到统计方法时间的目的。

在此过程中就利用到了 ByteBuddy。下面就是 ButeBuddy如何实现的。

添加依赖

首先将下面的依赖添加到 pom 文件中

image.png

由于在打包时声明了 jar-with-dependencies 该参数,所以最终 ByteBuddy 的架包也会被打入到 java-agent-demo 的架包中。

修改 premain 的教学方法:

1、原先的教学方法代码:publicstatic void premain(string agentparam,Instumentation inst){

System.out.println(“premain执行1”);

System.out.println(agentparam);

}

2.现在的教学方法:利用 ByteBuddy 提供的 AgentBuilder.Transformer 类别操作。代码如下:

Transformer=new AgentBuilder.Tansformer(){

Public DynamicType.Builder<?>transform(DynamicType.Builder<?>builder,TypeDescription typeDescription

//method 指定哪些方法需要被拦截,ElementMatcher.any 指定了所有的方法

//声明 intercept 拦截器

return builder.method(ElementMatchers.<MethodDescription>any())

intercept(MethodDelegation.to(MyInterceptor.class));

}

};

//type 指定了 agent 拦截的包名,以 com.agent 作为前缀

//指定了 transformer

//将配置安装到 Instrumentation

new AgentBuilder.Default().type(ElementMatchers.<TypeDescription>nameStartswith(prefix:“com.agent”)).transform(transformer).installon(inst);

}

将 MyInterceptor 拷贝在 Java 目录下新建一个类,代码如下:

Import net.bytebuddy.implementation.bind.annotation.origin;

public class MyInterceptor{

@RuntimeType

public static object intercept(@origin Method method,

@supercall Callable<?>caallable){

Long start=System.currentTimeMillis();

Try{

Return callable.call();

}finally{

System.out.println(method.getName()+“:”+

(system.currentTimeMillis()-start)+“ms”);

}

}

3.对以上代码文件进行打包

image.png

打包过后修改 main 函数

4.首先要把包名改成

image.png

com.agent

5.修改 main 方法代码:

Pakage com.agent;Public static void main(string[]args)throws InterruptedException{

System.out.println(“main方法执行”)

Thread.sleep(millis:1000L);

}

}

6.执行

执行时间是由拦截器来拦截同时打印出来。

如果将包名替换拦截器就和原先设置的包名匹配不上,当执行 main 方法时就不会出现执行时间了。

如图:

image.png

说明 Java agent 和 ButeBuddy 组合起来就可以对方法的执行时间进行统计。

7.要点总结

Myinterceptor 拦截器是在 PreMainAgent 定义

transformer 转换器的时候指定的, Myintercepter 拦截器会对所有方法进行拦截,同时这些方法一定要存在于com.agent 这些包下才能生效。

修改包名时一定要将包名改为 com.agent。

执行的时候还要在 premain 方法里声明一个 transformer转

换器,同时将转换器安装到 instrumentation 中。

相关文章
|
1天前
|
消息中间件 Java 应用服务中间件
JVM实战—1.Java代码的运行原理
本文介绍了Java代码的运行机制、JVM类加载机制、JVM内存区域及其作用、垃圾回收机制,并汇总了一些常见问题。
JVM实战—1.Java代码的运行原理
|
7天前
|
存储 缓存 安全
【原理】【Java并发】【volatile】适合初学者体质的volatile原理
欢迎来到我的技术博客!我是一名热爱编程的开发者,梦想是写出高端的CRUD应用。2025年,我正在沉淀自己,博客更新速度也在加快。在这里,我会分享关于Java并发编程的深入理解,尤其是volatile关键字的底层原理。 本文将带你深入了解Java内存模型(JMM),解释volatile如何通过内存屏障和缓存一致性协议确保可见性和有序性,同时探讨其局限性及优化方案。欢迎订阅专栏《在2B工作中寻求并发是否搞错了什么》,一起探索并发编程的奥秘! 关注我,点赞、收藏、评论,跟上更新节奏,让我们共同进步!
80 8
【原理】【Java并发】【volatile】适合初学者体质的volatile原理
|
11天前
|
开发框架 Java 开发工具
【Java全栈学习笔记-U1-day01】Java介绍
本笔记整理了Java学习的基础内容,涵盖程序理解、Java语言特性、JDK安装与配置、Java程序开发工具及编写步骤。重点介绍了Java程序的基本结构、编译和运行过程,以及输出语句的使用。通过实例演示了IDEA创建Java程序的方法,并强调了编码规范和注意事项。适合初学者复习和交流学习。 主要内容: 1. 理解程序:计算机组成、程序定义。 2. 简介:Java语言特点、技术平台、JDK作用。 3. 编写Java程序:编写、编译、运行步骤,基本结构。 4. 输出语句 5. DEA使用:新建工程、保存位置、文件介绍、新建类。 6. 扩展:注释、代码规范、大小写敏感、缩进等。
|
1月前
|
存储 算法 Java
【JAVA】生成accessToken原理
在Java中,生成accessToken用于身份验证和授权,确保合法用户访问受保护资源。流程包括:1. 身份验证(如用户名密码、OAuth 2.0);2. 生成唯一且安全的令牌;3. 设置令牌有效期并存储;4. 客户端传递令牌,服务器验证其有效性。常见场景为OAuth 2.0协议,涉及客户端注册、用户授权、获取授权码和换取accessToken。示例代码展示了使用Apache HttpClient库模拟OAuth 2.0获取accessToken的过程。
|
1月前
|
安全 Java 开发者
【JAVA】封装多线程原理
Java 中的多线程封装旨在简化使用、提高安全性和增强可维护性。通过抽象和隐藏底层细节,提供简洁接口。常见封装方式包括基于 Runnable 和 Callable 接口的任务封装,以及线程池的封装。Runnable 适用于无返回值任务,Callable 支持有返回值任务。线程池(如 ExecutorService)则用于管理和复用线程,减少性能开销。示例代码展示了如何实现这些封装,使多线程编程更加高效和安全。
|
2月前
|
存储 Java BI
java怎么统计每个项目下的每个类别的数据
通过本文,我们详细介绍了如何在Java中统计每个项目下的每个类别的数据,包括数据模型设计、数据存储和统计方法。通过定义 `Category`和 `Project`类,并使用 `ProjectManager`类进行管理,可以轻松实现项目和类别的数据统计。希望本文能够帮助您理解和实现类似的统计需求。
120 17
|
3月前
|
监控 Java API
探索Java NIO:究竟在哪些领域能大显身手?揭秘原理、应用场景与官方示例代码
Java NIO(New IO)自Java SE 1.4引入,提供比传统IO更高效、灵活的操作,支持非阻塞IO和选择器特性,适用于高并发、高吞吐量场景。NIO的核心概念包括通道(Channel)、缓冲区(Buffer)和选择器(Selector),能实现多路复用和异步操作。其应用场景涵盖网络通信、文件操作、进程间通信及数据库操作等。NIO的优势在于提高并发性和性能,简化编程;但学习成本较高,且与传统IO存在不兼容性。尽管如此,NIO在构建高性能框架如Netty、Mina和Jetty中仍广泛应用。
70 3
|
3月前
|
安全 算法 Java
Java CAS原理和应用场景大揭秘:你掌握了吗?
CAS(Compare and Swap)是一种乐观锁机制,通过硬件指令实现原子操作,确保多线程环境下对共享变量的安全访问。它避免了传统互斥锁的性能开销和线程阻塞问题。CAS操作包含三个步骤:获取期望值、比较当前值与期望值是否相等、若相等则更新为新值。CAS广泛应用于高并发场景,如数据库事务、分布式锁、无锁数据结构等,但需注意ABA问题。Java中常用`java.util.concurrent.atomic`包下的类支持CAS操作。
104 2
|
4月前
|
安全 Java
Java中WAIT和NOTIFY方法调用时机的深层解析
在Java多线程编程中,`wait()`和`notify()`方法的正确使用对于线程间的协调至关重要。这两个方法必须在同步块或同步方法中调用,这一规定的深层原因是什么呢?本文将深入探讨这一机制。
68 5
|
4月前
|
JSON 算法 数据挖掘
基于图论算法有向图PageRank与无向图Louvain算法构建指令的方式方法 用于支撑qwen agent中的统计相关组件
利用图序列进行数据解读,主要包括节点序列分析、边序列分析以及结合节点和边序列的综合分析。节点序列分析涉及节点度分析(如入度、出度、度中心性)、节点属性分析(如品牌、价格等属性的分布与聚类)、节点标签分析(如不同标签的分布及标签间的关联)。边序列分析则关注边的权重分析(如关联强度)、边的类型分析(如管理、协作等关系)及路径分析(如最短路径计算)。结合节点和边序列的分析,如子图挖掘和图的动态分析,可以帮助深入理解图的结构和功能。例如,通过子图挖掘可以发现具有特定结构的子图,而图的动态分析则能揭示图随时间的变化趋势。这些分析方法结合使用,能够从多个角度全面解读图谱数据,为决策提供有力支持。
179 0

热门文章

最新文章