前言
在之前dubbo分散式框架中講到了如何利用dubbo來搭建一個微服務專案。其中還有一些值得優化提高開發效率的地方,比如日誌:
當我們一個專案拆分為N多個微服務之後,當其中一個呼叫另一個服務出現了問題,首先第一步自然是檢視日誌。
出現問題的有很多情況,如提供方自身程式碼的問題,呼叫方的姿勢不對等。
自身的問題這個管不了,但是我們可以對每一個入參、返回都加上日誌,這樣首先就可以判斷呼叫方是否姿勢不對了。
為了規範日誌已經後續的可擴充套件,我們可以單獨提供一個外掛給每個專案使用即可。
效果如下:
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
進行擴充。
定義實體
首先定義一個實體類用於儲存呼叫過程中的一些資料:
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 ;
}
}
}複製程式碼
邏輯非常簡單,只是對呼叫過程、異常、成功之後列印相應的日誌而已。
但是有個地方要注意一下:
需要在resource
目錄下加上META-INF.dubbo/com.alibaba.dubbo.rpc.Filter
檔案。
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>複製程式碼
在攔截器中最好不要加上一些耗時任務,需要考慮到效能問題。、
個人部落格地址:crossoverjie.top。
GitHub地址:github.com/crossoverJi…。