中文JAVA技術平等自由協作創造

          Java專題文章博客和開源

          常用鏈接

          統計

          最新評論

          基于Spring AOP實現對外接口的耗時監控

            AOP是Spring的核心,Spring不但自身對多種框架的集成是基于AOP,并且以非常方便的形式暴露給普通使用者。以前用AOP不多,主要是因為它以橫截面的方式插入到主流程中,擔心導致主流程代碼不夠清晰,定位問題不夠方便,而在計費二期的項目里需要一個很適合用AOP來做的功能,就是要把對外接口和所調用的外部接口的耗時時間給記錄下來,這個需求主要來自于計費一期的聯調,常常發生系統間交互不夠順暢的情況,這就需要看每個接口調用時間來判定是誰的問題。

            計費中心是整個后臺系統的中間環節,與其他系統交互很多,這樣的接口也很多,如果在每個接口的調用前后加時間記錄比較繁瑣,也影響主流程代碼的美觀,因此比較優雅的方式是用AOP,在不侵入原有代碼的情況下,加上對接口調用的監控,并且可以在不需要的時候很容易移除。今天嘗試了一下,感覺還挺好用,下面講述一下實施步驟:托福答案

            1)引入包依賴

            本項目基于maven構建,因此加上包依賴比較方便,我需要的AOP依賴庫有以下三個:

            [xhtml]

            <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>

            <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:

            [xhtml]

            <?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>

            <?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:

            [java]

            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");

            }

            }

            }

            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

           

          posted on 2013-09-02 09:24 好不容易 閱讀(295) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          PK10開獎 PK10開獎
          主站蜘蛛池模板: 大城县| 福州市| 伊金霍洛旗| 锡林郭勒盟| 长子县| 秭归县| 石台县| 平安县| 称多县| 扎赉特旗| 瑞金市| 九龙城区| 大港区| 临湘市| 嘉义县| 阿克陶县| 苏尼特右旗| 钟祥市| 凯里市| 榕江县| 琼海市| 象州县| 垣曲县| 郸城县| 壶关县| 信阳市| 双鸭山市| 洮南市| 二手房| 晋江市| 瓮安县| 上虞市| 通海县| 安吉县| 增城市| 潞西市| 盖州市| 岢岚县| 太湖县| 郎溪县| 胶南市|