基于Spring AOP实现对外接口的耗时监控
AOP是Spring的核心,Spring不但自身对多种框架的集成是基于AOP,并且以非常方便的形式暴露给普通使用者。以前用AOP不多,主要是因为它以横截面的方式插入到主流程中,担心导致主流程代码不够清晰,定位问题不够方便,而在计费二期的项目里需要一个很适合用AOP来做的功能,就是要把对外接口和所调用的外部接口的耗时时间给记录下来,这个需求主要来自于计费一期的联调,常常发生系统间交互不够顺畅的情况,这就需要看每个接口调用时间来判定是谁的问题。
计费中心是整个后台系统的中间环节,与其他系统交互很多,这样的接口也很多,如果在每个接口的调用前后加时间记录比较繁琐,也影响主流程代码的美观,因此比较优雅的方式是用AOP,在不侵入原有代码的情况下,加上对接口调用的监控,并且可以在不需要的时候很容易移除。今天尝试了一下,感觉还挺好用,下面讲述一下实施步骤:
1)引入包依赖
本项目基于maven构建,因此加上包依赖比较方便,我需要的AOP依赖库有以下三个:
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-aop</artifactId>
- <version>2.5.6</version>
- </dependency>
- <dependency>
- <groupId>org.aspectj</groupId>
- <artifactId>aspectjweaver</artifactId>
- <version>1.6.1</version>
- </dependency>
- <dependency>
- <groupId>org.aspectj</groupId>
- <artifactId>aspectjrt</artifactId>
- <version>1.6.1</version>
- </dependency>
2)加上AOP的Spring配置文件
billing-spring-aop.xml:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
- <bean id="openApiLogAspect" class="com.alibaba.itbu.billing.framework.aop.OpenApiLogAspect">
- </bean>
- <aop:config>
- <!-- 配置aspect切面类 -->
- <aop:aspect ref="openApiLogAspect">
- <!-- 配置pointcut,即切入点,对哪些类的哪些方法起到AOP的作用 -->
- <aop:pointcut id="EsbPriceService"
- expression="execution(* org.esb.biz.product.EsbPriceService.*(..))" />
- <aop:pointcut id="EsbProductService"
- expression="execution(* org.esb.biz.product.EsbProductService.*(..))" />
- <aop:pointcut id="IAuthorizeControllerService"
- expression="execution(* com.alibaba.bss.pc2.server.remoting.IAuthorizeControllerService.*(..))" />
- <aop:pointcut id="IOpenApiOrderItemService"
- expression="execution(* com.alibaba.itbu.billing.api.collect.IOpenApiOrderItemService.*(..))" />
- <aop:pointcut id="IOpenApiBillingCollectService"
- expression="execution(* com.alibaba.itbu.billing.api.collect.IOpenApiBillingCollectService.*(..))" />
- <aop:pointcut id="IOpenApiInvoiceService"
- expression="execution(* com.alibaba.itbu.billing.api.invoice.IOpenApiInvoiceService.*(..))" />
- <aop:pointcut id="IOpenApiChargeProductInfoService"
- expression="execution(* com.alibaba.itbu.billing.api.collect.IOpenApiChargeProductInfoService.*(..))" />
- <!-- 配置advice,这里采用在业务方法执行前后进行拦截 -->
- <aop:around method="logExecuteTime" pointcut-ref="EsbPriceService" />
- <aop:around method="logExecuteTime" pointcut-ref="EsbProductService" />
- <aop:around method="logExecuteTime" pointcut-ref="IAuthorizeControllerService" />
- <aop:around method="logExecuteTime" pointcut-ref="IOpenApiOrderItemService" />
- <aop:around method="logExecuteTime" pointcut-ref="IOpenApiBillingCollectService" />
- <aop:around method="logExecuteTime" pointcut-ref="IOpenApiInvoiceService" />
- <aop:around method="logExecuteTime" pointcut-ref="IOpenApiChargeProductInfoService" />
- </aop:aspect>
- </aop:config>
- </beans>
我是基于配置完成AOP接入,这样做的好处是不需要对原有主流程代码有任何浸入,并且也比较容易移除本AOP的拦截,这段代码主要就是配置aspect、pointcut和advice
3)编写监控耗时的advice
OpenApiLogAspect:
- public class OpenApiLogAspect {
- private static LoggerService logger = LoggerFactory.getLogger(OpenApiLogAspect.class);
- public Object logExecuteTime(ProceedingJoinPoint joinPoint) throws Throwable{
- Date start = new Date();
- try{
- return joinPoint.proceed(joinPoint.getArgs());
- }catch(Exception err){
- throw err;
- }finally{
- Date end = new Date();
- logger.info("OpenApiExecuteTime:"+joinPoint.getSignature().getName()+" takes "+(end.getTime()-start.getTime())+"ms");
- }
- }
- }
此段代码就是基于around的方式来拦截接口调用,在实际调用的前后加上时间记录,并最后在日志里打印出时间差。其中joinPoint.proceed(joinPoint.getArgs());是对实际接口的调用。
4)使监控可以配置化
此功能只会在调试阶段使用,并不需要在生产环境中运行,因此需要可以配置是否监控接口。实施这个配置化很简单,只需要通过配置决定是否把aop spring的配置文件加入到容器里就可以了,因此在总容器applicationContext.xml.vm里加上如下代码:
#if(${monitor_openapi_showTime}=="true") <import resource="classpath*:bean/billing-spring-aop.xml" /> #end
在编译打包过程中会根据变量monitor_openapi_showTime来决定是否把billing-spring-aop.xml引入进来
5)运行效果
在监控开启的情况下,若发生接口调用,能从日志里看到如下记录:
2010-01-08 18:30:13,197 [OpenApiLogAspect.java:20] [com.alibaba.itbu.billing.framework.aop.OpenApiLogAspect] INFO com.alibaba.itbu.billing.framework.aop.OpenApiLogAspect :: OpenApiExecuteTime:installOrderItem takes 71ms 2010-01-08 18:30:27,188 [OpenApiLogAspect.java:20] [com.alibaba.itbu.billing.framework.aop.OpenApiLogAspect] INFO com.alibaba.itbu.billing.framework.aop.OpenApiLogAspect :: OpenApiExecuteTime:installOrderItem takes 0ms 2010-01-08 18:30:37,838 [OpenApiLogAspect.java:20] [com.alibaba.itbu.billing.framework.aop.OpenApiLogAspect] INFO com.alibaba.itbu.billing.framework.aop.OpenApiLogAspect :: OpenApiExecuteTime:installOrderItem takes 1ms
基于Spring AOP实现对外接口的耗时监控的更多相关文章
- Spring AOP在函数接口调用性能分析及其日志处理方面的应用
面向切面编程可以实现在不修改原来代码的情况下,增加我们所需的业务处理逻辑,比如:添加日志.本文AOP实例是基于Aspect Around注解实现的,我们需要在调用API函数的时候,统计函数调用的具体信 ...
- 基于Spring aop写的一个简单的耗时监控
前言:毕业后应该有一两年没有好好的更新博客了,回头看看自己这一年,似乎少了太多的沉淀了.让自己做一个爱分享的人,好的知识点拿出来和大家一起分享,一起学习. 背景: 在做项目的时候,大家肯定都遇到对一些 ...
- 基于Spring AOP的JDK动态代理和CGLIB代理
一.AOP的概念 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的 ...
- spring aop实现拦截接口请求打印日志
在spring配置 1编写自己的注解类 2.编写注解解析类 3.配置spring aop代理 (下面我使用注解 如使用配置 配置切点即可,有两种代理默认jdk代理 设置true 为cglib代理) / ...
- 基于Spring AOP实现的权限控制
1.AOP简介 AOP,面向切面编程,往往被定义为促使软件系统实现关注点的分离的技术.系统是由许多不同的组件所组成的,每一个组件负责一块特定的功能.除了实现自身核心功能之外,这些组件还经常承担着额外的 ...
- s2sh框架搭建(基于spring aop)
对于spring aop 是如何管理事务的,请看一下:http://bbs.csdn.net/topics/290021423 1.applicationContext.xml <?xml ve ...
- 利用Spring AOP切面对用户访问进行监控
开发系统时往往需要考虑记录用户访问系统查询了那些数据.进行了什么操作,尤其是访问重要的数据和执行重要的操作的时候将数记录下来尤显的有意义.有了这些用户行为数据,事后可以以用户为条件对用户在系统的访问和 ...
- 基于Spring Aop实现类似shiro的简单权限校验功能
在我们的web开发过程中,经常需要用到功能权限校验,验证用户是否有某个角色或者权限,目前有很多框架,如Shiro Shiro有基于自定义登录界面的版本,也有基于CAS登录的版本,目前我们的系统是基于C ...
- Spring AOP 介绍与基于接口的实现
热烈推荐:超多IT资源,尽在798资源网 声明:转载文章,为防止丢失所以做此备份. 本文来自公众号:程序之心 原文地址:https://mp.weixin.qq.com/s/vo94gVyTss0LY ...
随机推荐
- Unity3D脚本中文系列教程(三)
http://dong2008hong.blog.163.com/blog/static/4696882720140302323886/ Unity3D脚本中文系列教程(二) 示,属性不被序列化或显示 ...
- C# 委托的”四步走“
看了一本<深入了解C#>感觉很不错,对于委托的讲解,给大家摘录了下来! 1.什么是委托 我的拙见:委托就是将方法作为参数,进行传递的 书中的记载:将某种行为“包含”在一个对象中,这个对象可 ...
- java基础知识回顾之javaIO类---FileWriter和FileReader
FileWriter类的构造方法定义如下: 1.public FileWriter(File file)throws IOException 字符流的操作比字节流操作好在一点,就是可以直接输出字符串了 ...
- Opc
http://www.tuicool.com/articles/nymUz2 http://blog.chinaunix.net/uid-20692368-id-3434001.html http:/ ...
- POJ2251Dungeon Master
http://poj.org/problem?id=2251 题意 : 就是迷宫升级版,从以前的一个矩阵也就是一层,变为现在的L层," . "是可以走,但是“#”不可以走,从S走到 ...
- Strust2最基本使用
制作一个登陆表单,然后在另一个页面显示提交的内容,简单的一个小工程. 页面: //login.jsp <form action="login.action" method=& ...
- mac 下周期调度命令或脚本
crontab 是在linux服务器上部署定时任务的方法 0 5 * * * /usr/bin/python /data/www/tools/mysql_backup.py cmd之前有5个项目要填, ...
- 心情记录&考试总结 3.30
并不知道现在要干什么,本人像是一只大颓狗 Em..怎么说呢,今天考完了一场奇怪的试 准确的说,画风很不正常的试 第一题集体爆零 第二题暴力20分 第三题暴力40分,乱搞有加成 改题的话, 第一题有奇怪 ...
- CF 317D Game with Powers
题解: 将一个数的指数看着一个堆,问题变成这些堆的异或值 分析一个堆的情况,打SG表. #include<stdio.h> #include<string.h> ]; char ...
- s3cmd的安装与使用
s3cmd 是一款 Amazon S3 命令行工具.它不仅能上传.下载.同步,还能设置权限,下面是完整的安装使用指南. 主要是还是用来储存日志文件或者其他什么资料. https://wangyan. ...