SSM(十二) dubbo日誌插件

dubbo-filter.jpg

前言

在以前dubbo分佈式框架中講到了如何利用dubbo來搭建一個微服務項目。其中還有一些值得優化提升開發效率的地方,好比日誌:javascript

當咱們一個項目拆分爲N多個微服務以後,當其中一個調用另外一個服務出現了問題,首先第一步天然是查看日誌。 java

出現問題的有不少狀況,如提供方自身代碼的問題,調用方的姿式不對等。git

自身的問題這個管不了,可是咱們能夠對每個入參、返回都加上日誌,這樣首先就能夠判斷調用方是否姿式不對了。github

爲了規範日誌已經後續的可擴展,咱們能夠單獨提供一個插件給每一個項目使用便可。spring

效果以下:sql

2017-04-25 15:15:38,968 DEBUG [com.alibaba.dubbo.remoting.transport.DecodeHandler] -  [DUBBO] Decode decodeable message com.alibaba.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation, dubbo version: 2.5.3, current host: 127.0.0.1
2017-04-25 15:15:39,484 DEBUG [com.crossoverJie.dubbo.filter.DubboTraceFilter] - dubbo請求數據:{"args":[1],"interfaceName":"com.crossoverJie.api.UserInfoApi","methodName":"getUserInfo"}
2017-04-25 15:15:39,484 INFO [com.crossoverJie.api.impl.UserInfoApiImpl] - 用戶查詢Id=1
2017-04-25 15:15:39,505 DEBUG [org.mybatis.spring.SqlSessionUtils] - Creating a new SqlSession
2017-04-25 15:15:39,525 DEBUG [org.mybatis.spring.SqlSessionUtils] - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6f56b29] was not registered for synchronization because synchronization is not active
2017-04-25 15:15:39,549 DEBUG [org.mybatis.spring.transaction.SpringManagedTransaction] - JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@778b3121] will not be managed by Spring
2017-04-25 15:15:39,555 DEBUG [com.crossoverJie.api.dubbo.dao.T_userDao.selectByPrimaryKey] - ==>  Preparing: select id, username, password,roleId from t_user where id = ? 
2017-04-25 15:15:39,591 DEBUG [com.crossoverJie.api.dubbo.dao.T_userDao.selectByPrimaryKey] - ==> Parameters: 1(Integer)
2017-04-25 15:15:39,616 DEBUG [com.crossoverJie.api.dubbo.dao.T_userDao.selectByPrimaryKey] - <== 1="" total:="" 2017-04-25="" 15:15:39,616="" debug="" [com.alibaba.druid.pool.preparedstatementpool]="" -="" {conn-10003,="" pstmt-20000}="" enter="" cache="" 15:15:39,617="" [org.mybatis.spring.sqlsessionutils]="" closing="" non="" transactional="" sqlsession="" [org.apache.ibatis.session.defaults.defaultsqlsession@6f56b29]="" 15:15:45,473="" info="" [com.crossoverjie.dubbo.filter.dubbotracefilter]="" dubbo執行成功="" 15:15:45,476="" dubbo返回數據{"args":[{"id":1,"password":"123456","roleid":1,"username":"crossoverjie"}],"interfacename":"com.crossoverjie.api.userinfoapi","methodname":"getuserinfo"}<="" code="">
  
  
  

 複製代碼

dubbo filter拓展

參考官方文檔,咱們能夠經過com.alibaba.dubbo.rpc.Filter進行拓展。apache

定義實體

首先定義一個實體類用於保存調用過程當中的一些數據:api

public class FilterDesc {

    private String interfaceName ;//接口名
    private String methodName ;//方法名
    private Object[] args ;//參數
    //省略getter setter
}複製代碼

DubboTraceFilter具體攔截邏輯

@Activate(group = Constants.PROVIDER, order = -999)
public class DubboTraceFilter implements Filter{

    private static final Logger logger = LoggerFactory.getLogger(DubboTraceFilter.class);

    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {

        try {
            FilterDesc filterReq = new FilterDesc() ;
            filterReq.setInterfaceName(invocation.getInvoker().getInterface().getName());
            filterReq.setMethodName(invocation.getMethodName()) ;
            filterReq.setArgs(invocation.getArguments());

            logger.debug("dubbo請求數據:"+JSON.toJSONString(filterReq));

            Result result = invoker.invoke(invocation);
            if (result.hasException() && invoker.getInterface() != GenericService.class){
                logger.error("dubbo執行異常",result.getException());
            }else {
                logger.info("dubbo執行成功");

                FilterDesc filterRsp = new FilterDesc() ;
                filterRsp.setMethodName(invocation.getMethodName());
                filterRsp.setInterfaceName(invocation.getInvoker().getInterface().getName());
                filterRsp.setArgs(new Object[]{result.getValue()});
                logger.debug("dubbo返回數據"+JSON.toJSONString(filterRsp));

            }
            return result ;

        }catch (RuntimeException e){
            logger.error("dubbo未知異常" + RpcContext.getContext().getRemoteHost()
                    + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()
                    + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
            throw e ;
        }
    }
}複製代碼

邏輯很是簡單,只是對調用過程、異常、成功以後打印相應的日誌而已。session

可是有個地方要注意一下:
須要在resource目錄下加上META-INF.dubbo/com.alibaba.dubbo.rpc.Filter文件。mybatis

dubboTraceFilter=com.crossoverJie.dubbo.filter.DubboTraceFilter複製代碼

目錄結構以下:

src
 |-main
    |-java
        |-com
            |-xxx
                |-XxxFilter.java (實現Filter接口)
    |-resources
        |-META-INF
            |-dubbo
                |-com.alibaba.dubbo.rpc.Filter (純文本文件,內容爲:xxx=com.xxx.XxxFilter)複製代碼

總結

該項目已經託管到GitHub:
github.com/crossoverJi…

使用方法

安裝

cd /SSM-DUBBO-FILTER複製代碼
mvn clean複製代碼
mvn install複製代碼

使用

在服務提供的項目中加上依賴,這樣每次調用都會打上日誌。

<dependency>
    <groupId>com.crossoverJie</groupId>
    <artifactId>SSM-TRACE-FILTER</artifactId>
    <version>1.0.0</version>
</dependency>複製代碼

在攔截器中最好不要加上一些耗時任務,須要考慮到性能問題。

項目地址:github.com/crossoverJi…

我的博客地址:crossoverjie.top

GitHub地址:github.com/crossoverJi…

weixin
相關文章
相關標籤/搜索