91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

微服務如何實現簡單的分布式日志追蹤

發布時間:2022-01-12 17:55:12 來源:億速云 閱讀:212 作者:柒染 欄目:服務器

這期內容當中小編將會給大家帶來有關微服務如何實現簡單的分布式日志追蹤,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

最近想給項目添加一個簡單的分布式請求跟蹤功能,從前端發起請求到網關,再從網關調用 Spring Cloud  的微服務,這些過程中希望能從日志中看到一個分布式 ID 的鏈路,通過請求的 ID 可以追蹤整一條鏈路,方便問題的排查。

現成的方案自然是使用 SkyWalking 、 Spring Cloud Sleuth 、Zipkin  之類的組件,但是想到主要的目的記錄一個可以一直貫通各個服務的 ID,方便日志查詢,也就不想引入太多復雜的組件,最終決定通過 MDC 在日志中輸出追蹤的  ID,然后在 Feign 和 RestTemplate 中將請求 ID 在微服務中傳遞。

主要包括幾個步驟:

  • 從前端生成請求 ID 并加入請求頭帶入網關

  • 網關通過 WebFilter 攔截并加入 MDC 中,在 log 中輸出

  • 在 Feign 和 RequestTemplate 中將請求 ID 在帶到 HTTP 的 Header 中微服務傳遞

  • 各個微服務同樣通過 WebFilter 實現攔截并加入 MDC,在 log 中輸出

MDC

MDC(Mapped Diagnostic Context,映射調試上下文)是 Log4j 和 Logback  提供的一種方便在多線程條件下記錄日志的功能。 MDC 可以看成是一個與當前線程綁定的哈希表,可以往其中添加鍵值對。

MDC 的關鍵操作:

  • 向 MDC 中設置值:MDC.put(key, value);

  • 從 MDC 中取值:MDC.get(key);

  • 將 MDC 中內容打印到日志中:%X{key}

新增 TraceId 工具類

先新增一個 TraceIdUtils 工具類,用于定義 TRACE_ID 的常量值以及設置及生成 TRACE_ID  的方法,后續代碼中都是通過這個估計類進行操作。

import org.apache.commons.lang.RandomStringUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.MDC;  public class TraceIdUtils {     public static final String TRACE_ID = "traceId";     private static final int MAX_ID_LENGTH = 10;      /**      * 生成 traceId      */     private static String genTraceId() {         return RandomStringUtils.randomAlphanumeric(MAX_ID_LENGTH);     }      /**      * 設置 traceId      */     public static void setTraceId(String traceId) {         // 如果參數為空,則生成新 ID         traceId = StringUtils.isBlank(traceId) ? genTraceId() : traceId;         // 將 traceId 放到 MDC 中         MDC.put(TRACE_ID, StringUtils.substring(traceId, -MAX_ID_LENGTH));     }      /**      * 獲取 traceId      */     public static String getTraceId() {         // 獲取         String traceId = MDC.get(TRACE_ID);         // 如果 traceId 為空,則生成新 ID         return StringUtils.isBlank(traceId) ? genTraceId() : traceId;     } }

通過 WebFilter 添加 TraceId 過濾器

新增一個 GenericFilterBean ,從請求頭中獲取 TraceIdUtils.TRACE_ID  對應的值,該值在前端發起請求或者微服務之間傳遞都會帶上,如果沒有,則 TraceIdUtils.setTraceId 會生成一個。

import org.springframework.core.annotation.Order; import org.springframework.web.filter.GenericFilterBean;  @WebFilter(urlPatterns = "/*", filterName = "traceIdFilter") @Order(1) public class TraceIdFilter extends GenericFilterBean {     @Override     public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {         // traceId初始化         HttpServletRequest req = (HttpServletRequest) request;         String traceId = req.getHeader(TraceIdUtils.TRACE_ID);         TraceIdUtils.setTraceId(traceId);         // 執行后續過濾器         filterChain.doFilter(request, response);     } }

不要忘記在 SpringBoot 的啟動類加上 @ServletComponentScan 注解,否則自定義的 Filter 無法生效。其中  “com.yourtion.trace.filter” 是 TraceIdFilter 所在的包名。

@ServletComponentScan(basePackages = "com.yourtion.trace.filter") @SpringBootApplication public class MyApplication {      public static void main(String[] args) {         SpringApplication.run(MyApplication.class, args);     } }

在 Feign 上添加 TraceId

因為 @FeignClient 的代理類在執行的時候,會去使用使用到 Spring 上下文的  RequestInterceptor,所以自定義自己的攔截器,然后注入到 Spring 上下文中,這樣就可以在請求的上下文中添加自定義的請求頭。

import feign.RequestInterceptor; import feign.RequestTemplate; import org.springframework.stereotype.Service;  @Service public class FeignInterceptor implements RequestInterceptor {     @Override     public void apply(RequestTemplate template) {         template.header(TraceIdUtils.TRACE_ID, TraceIdUtils.getTraceId());     } }

在 RestTemplate 上添加 TraceId

還有一部分請求是通過 RestTemplate 發起的,之前我們是自己實現了 RestTemplateConfig  的配置類,這次在相關的配置上添加:

RestTemplate restTemplate = builder.additionalInterceptors((request, body, execution) -> {     request.getHeaders().add(TraceIdUtils.TRACE_ID, TraceIdUtils.getTraceId());     return execution.execute(request, body); }).build();

至此,鏈路上的 TraceId 添加已經完成,剩下的就是在日志中打印出來了。

修改 Log4j2 的 layout 格式

修改日志的layout格式,將MDC中的traceId打印出來:

<!-- 原始格式 --> <PatternLayout pattern="%5p %c:%L - %m %throwable{separator( --> )}%n"/>  <!-- 增加traceId的格式 --> <PatternLayout pattern="%5p traceId:%X{traceId} %c:%L - %m %throwable{separator( --> )}%n"/>

上述就是小編為大家分享的微服務如何實現簡單的分布式日志追蹤了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

民权县| 合肥市| 迭部县| 集安市| 武夷山市| 白河县| 灵山县| 凤庆县| 吉木萨尔县| 卓尼县| 蓬溪县| 吉首市| 绩溪县| 通海县| 玛曲县| 枣庄市| 闽清县| 德格县| 邵阳县| 建水县| 察雅县| 泸水县| 和硕县| 太谷县| 阿克苏市| 辽阳县| 逊克县| 保康县| 来凤县| 从化市| 平和县| 长阳| 个旧市| 淄博市| 苏尼特左旗| 阿克陶县| 睢宁县| 延庆县| 怀柔区| 翼城县| 北碚区|