zoukankan      html  css  js  c++  java
  • 记录一次TraceId的问题

             多服务部署的时候,各个服务通过httpClient进行调用时候,有时候出现问题,需要进行追查。但是如果没有一个标记,就会很迷茫,特别是多个服务来回调用,就无法快速定位问题。这个时候一般是使用MDC的 traceId来追踪。但是由于每个服务的traceId不同,在使用elk进行查询的时候,仍然不能快速定位。于是,决定统一traceId以方便快速定位。

          原理:

    发起请求经过Nginx的时候,第一次请求时 nginx 会生成X-Request-Id。 服务里面的拦截器会拦截获取,如果request的header头里面带有该X-Request-Id,则会直接读取,如果没有,会重新生成.  在使用mp-util的 MpHttpclient 时候,会将该值放到header头信息里面,以便在请求下个服务时候可以直接获取。从而从上游到下游统一traceId。

         

        具体使用就是:封装http包的header部分,在每个调用方法的header里面添加traceId给下游。每个服务自己定义拦截器,在拦截器里面进行拦截。如果含有traceId就进行输入到日志里面,如果没有,则创建。拦截器

      

    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 {
          //一、当前登录用户(用于日志输出)
     SSOLoginUser loginUser = WebSessionUtil.getCurrentLoginUser();
     if(loginUser==null) {
             MDC.put("loginUser", "【游客身份】");
     }else {
             MDC.put("loginUser", ""+ loginUser.getId() +"-"+ loginUser.getName() +"-"+ loginUser.getLoginName()+"");
     }
          //二、用于页面渲染
     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进行查询时候就方便多了:

     

  • 相关阅读:
    Ubuntu1404: 将VIM打造为一个实用的PythonIDE
    事前备份胜于事后恢复
    做事不应当拘泥于既定的循例
    简单生活
    《犹太人思考术》读后感
    产品开发与运维的中心准则
    Awk使用一例:获取ASCII可见字符
    使用Sed和Awk实现批量文件的文本替换
    编写更少bug的程序的六条准则
    【JS新手教程】JS中的split()方法,拆分字符串
  • 原文地址:https://www.cnblogs.com/thinkingandworkinghard/p/11387501.html
Copyright © 2011-2022 走看看