使用动态代理记录方法执行的时间

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 在大型系统中,我们经常需要监视我们系统执行的性能状况,当出现性能问题时,我们要能够迅速地找到瓶颈在什么地方。在程序的层面上来说,就是看哪个方法执行所消耗的时间很长。       使用动态代理可以非常方便的记录方法执行的时间,比如,下面的截图,就是ESBasic.

      在大型系统中,我们经常需要监视我们系统执行的性能状况,当出现性能问题时,我们要能够迅速地找到瓶颈在什么地方。在程序的层面上来说,就是看哪个方法执行所消耗的时间很长。

      使用动态代理可以非常方便的记录方法执行的时间,比如,下面的截图,就是ESBasic.Emit.Aop.Interceptors.MethodTimeInterceptor截获器记录的片段:

2009 - 4 - 17   18 : 50 : 12 :TY.Web.AgentInterface.IGameRecordDetailBL.GetPaginationData方法耗时:390ms
2009 - 4 - 17   18 : 50 : 16 :TY.Web.MemberInterface.IMemberBL.GetOne方法耗时:106ms
2009 - 4 - 17   18 : 50 : 23 :TY.Web.MemberInterface.IMemberBL.GetOne方法耗时:105ms
2009 - 4 - 17   18 : 50 : 23 :TY.Web.MemberInterface.IMemberBL.GetOne方法耗时:105ms
2009 - 4 - 17   18 : 50 : 24 :TY.Web.AgentInterface.IGameRecordDetailBL.GetPaginationData方法耗时:386ms
2009 - 4 - 17   18 : 50 : 30 :TY.Web.AgentInterface.IGameRecordDetailBL.GetPaginationData方法耗时:387ms
2009 - 4 - 17   18 : 50 : 35 :TY.Web.AgentInterface.IGameRecordDetailBL.GetPaginationData方法耗时:377ms
2009 - 4 - 17   18 : 50 : 43 :TY.Web.MemberInterface.IMemberBL.GetOne方法耗时:105ms
2009 - 4 - 17   18 : 51 : 14 :TY.Web.MemberInterface.IGameBenefitBL.GetMemberBenefitData方法耗时:714ms

 

      在我们常见的三层架构中,我们可能需要记录UI层调用BL层的每个方法所执行的时间,那我们可以这样做。假设BL提供给UI访问的接口为IBL(可能有多个,如IBL1,IBL2,IBL3,......),BL通过Remoting的方式发布它的服务。

     // BL层给UI层调用的接口
     public   interface  IBL
    {        
    }
    
// BL的实现
     public   class  BLObject IBL
    {
    }

      那么,我们让BL不直接发布实现了IBL接口的对象(BLObject),而是发布拦截了这个对象的动态代理,就像这样:

IMethodTimeLogger logger = new MethodTimeLogger(new FileAgileLogger("TimeLogger.txt") ,100) ; 
IBL blObject 
= ...; //BLObject 的实例
IBL blObjectProxy = DynamicProxyFactory.CreateAopProxy<IBL>(blObject, nullnew MethodTimeInterceptor(logger));

 

      blObjectProxy即是拦截了blObject调用的动态代理,它和BLObject 一样实现了IBL接口,并且将所有的调用转发给blObject,而且记录了blObject每个方法执行的时间。我们可以将blObjectProxy对象发布为Remoting,这样就可以记录下BL每个方法的执行时间了。

 

      在上面的例子中,IMethodTimeLogger 接口是用于记录时间的记录器接口,我们可以将时间记录到日志文件,当然也可以记录到数据库或其他地方,你只要实现IMethodTimeLogger 接口就可以了。这里我们将时间记录到TimeLogger.txt文件,注意,MethodTimeLogger 的第二个参数100,表示只记录那些执行时间超过100ms的方法调用,因为如果要记录所有的方法调用的话,在大型系统中日志可能会在很短的时间内就变得非常的庞大,这样反而不利于日志查看。

 

      再回到上面的日志片段,我们看到,日志记录了BL接口中具体方法的调用时间,执行所消耗的时长,这样我们就可以很方便的找到性能的瓶颈是在那个方法的调用上产生的了。

      上述例子中所用到的类都位于ESBasic.dll中,你可以从这里下载进行试验。ESBasic中的动态代理技术是基于Emit实现的,有兴趣的话你可以使用Reflector来查看其实现原理。

      关于ESBasic中动态代理实现的更多介绍,可以参考我的这两篇文章:动态代理DynamicProxy 介绍  和 使用动态代理,提高工作效率


 

 

相关实践学习
通过日志服务实现云资源OSS的安全审计
本实验介绍如何通过日志服务实现云资源OSS的安全审计。
目录
相关文章
|
12月前
|
NoSQL C语言 索引
十二个C语言新手编程时常犯的错误及解决方式
C语言初学者常遇错误包括语法错误、未初始化变量、数组越界、指针错误、函数声明与定义不匹配、忘记包含头文件、格式化字符串错误、忘记返回值、内存泄漏、逻辑错误、字符串未正确终止及递归无退出条件。解决方法涉及仔细检查代码、初始化变量、确保索引有效、正确使用指针与格式化字符串、包含必要头文件、使用调试工具跟踪逻辑、避免内存泄漏及确保递归有基准情况。利用调试器、编写注释及查阅资料也有助于提高编程效率。避免这些错误可使代码更稳定、高效。
1571 12
|
监控 安全 Java
【面试题】面试必备我跟面试官聊了一个小时线程池!
【面试题】面试必备我跟面试官聊了一个小时线程池!
1109 1
|
传感器 物联网 区块链
智能革命的引擎:区块链、物联网与虚拟现实技术的融合与创新##
在21世纪的信息时代,新兴技术正以前所未有的速度改变着我们的生活和工作方式。本文深入探讨了区块链技术、物联网(IoT)和虚拟现实(VR)这三大前沿技术的发展趋势及其在不同领域的创新应用。通过分析这些技术如何相互促进、融合,共同塑造一个更加智能、互联的世界,揭示了它们对未来社会可能产生的深远影响。不同于传统的技术性摘要,本文旨在以一种通俗易懂且条理清晰的方式,引导读者思考新技术背后的哲理性内涵及其对人生意义的启示。 ##
176 27
|
消息中间件 NoSQL Java
2024年高频Java面试题集锦(含答案),让你的面试之路畅通无阻!
或许这份面试题还不足以囊括所有 Java 问题,但有了它,我相信你一定不会“败”的很惨,因为有了它,足以应对目前市面上绝大部分的 Java 面试了,因为这篇文章不论是从深度还是广度上来讲,都已经囊括了非常多的知识点了。
|
存储 算法 机器人
路径规划的艺术:不同路径 II 的算法深掘【python力扣63题】
路径规划的艺术:不同路径 II 的算法深掘【python力扣63题】
|
缓存 监控 安全
Spring AOP 详细深入讲解+代码示例
Spring AOP(Aspect-Oriented Programming)是Spring框架提供的一种面向切面编程的技术。它通过将横切关注点(例如日志记录、事务管理、安全性检查等)从主业务逻辑代码中分离出来,以模块化的方式实现对这些关注点的管理和重用。 在Spring AOP中,切面(Aspect)是一个模块化的关注点,它可以跨越多个对象,例如日志记录、事务管理等。切面通过定义切点(Pointcut)和增强(Advice)来介入目标对象的方法执行过程。 切点是一个表达式,用于匹配目标对象的一组方法,在这些方法执行时切面会被触发。增强则定义了切面在目标对象方法执行前、执行后或抛出异常时所
16447 4
|
缓存 负载均衡 网络协议
【亮剑】一次完整的HTTP请求的重要性和详细过程
【4月更文挑战第30天】本文介绍了HTTP请求的重要性和详细过程。首先,DNS解析将域名转换为IP地址,通过递归和迭代查询找到目标服务器。接着,TCP三次握手建立连接。然后,客户端发送HTTP请求,服务器处理请求并返回响应。最后,理解这个过程有助于优化网站性能,如使用DNS缓存、HTTP/2、Keep-Alive、CDN和负载均衡等实践建议。
534 0
|
算法 安全 网络安全
HTTPS加密原理解析:保障通信安全的密码学算法
HTTPS加密原理解析:保障通信安全的密码学算法
1067 0
|
缓存 安全 Java
什么是线程安全?如何保证线程安全?Java 中保证线程安全的方法有哪些?【重要】
什么是线程安全?如何保证线程安全?Java 中保证线程安全的方法有哪些?【重要】
3432 0
|
安全 Java 编译器
java(Class 常用方法 获取Class对象六种方式 动态和静态加载 类加载流程)
java(Class 常用方法 获取Class对象六种方式 动态和静态加载 类加载流程)
1295 0