记录一次TraceId的问题

 

 

 

         多服务部署的时候,各个服务经过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

 

相关文章
相关标签/搜索