多服務部署的時候,各個服務經過httpClient進行調用時候,有時候出現問題,須要進行追查。可是若是沒有一個標記,就會很迷茫,特別是多個服務來回調用,就沒法快速定位問題。這個時候通常是使用MDC的 traceId來追蹤。可是因爲每一個服務的traceId不一樣,在使用elk進行查詢的時候,仍然不能快速定位。因而,決定統一traceId以方便快速定位。nginx
原理:dom
發起請求通過Nginx的時候,第一次請求時 nginx 會生成X-Request-Id。 服務裏面的攔截器會攔截獲取,若是request的header頭裏面帶有該X-Request-Id,則會直接讀取,若是沒有,會從新生成. 在使用mp-util的 MpHttpclient 時候,會將該值放到header頭信息裏面,以便在請求下個服務時候能夠直接獲取。從而從上游到下游統一traceId。ide
具體使用就是:封裝http包的header部分,在每一個調用方法的header裏面添加traceId給下游。每一個服務本身定義攔截器,在攔截器裏面進行攔截。若是含有traceId就進行輸入到日誌裏面,若是沒有,則建立。攔截器spa
public class InitRequestAuthDataFilter extends OncePerRequestFilter { // log 追蹤ID private final static String TRACE_KEY = "X-Request-Id"; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException { //1、當前登陸用戶(用於日誌輸出) SSOLoginUser loginUser = WebSessionUtil.getCurrentLoginUser(); if(loginUser==null) { MDC.put("loginUser", "【遊客身份】"); }else { MDC.put("loginUser", "【"+ loginUser.getId() +"-"+ loginUser.getName() +"-"+ loginUser.getLoginName()+"】"); } //2、用於頁面渲染 request.setAttribute("currentLoginUser", loginUser ); //先從param裏取,沒有的話從header裏取,尚未的話再建立 String reqId = request.getParameter("X-Request-Id"); if(reqId==null || "".equals(reqId.trim()) ) { reqId = request.getHeader("X-Request-Id"); } if(reqId==null || "".equals(reqId.trim()) ) { reqId = UUID.randomUUID().toString().replace("-", ""); } MDC.put(TRACE_KEY, reqId); //該traceId是讓日誌打印出來的key值 MDC.put("traceId",reqId); /**防止MDC 屢次生成,引入的sq-component-log 有攔截 header 頭信息**/ logger.info("header:" + request.getHeader("X-Request-Id")); filterChain.doFilter(request, response); MDC.remove(TRACE_KEY); } }
以後再日子裏面進行驗證日誌
沒問題後,再經過elk進行查詢時候就方便多了:code