真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

微服務(wù)如何實(shí)現(xiàn)簡(jiǎn)單的分布式日志追蹤

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)微服務(wù)如何實(shí)現(xiàn)簡(jiǎn)單的分布式日志追蹤,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

在南雄等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì) 網(wǎng)站設(shè)計(jì)制作按需定制制作,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),成都全網(wǎng)營(yíng)銷推廣,成都外貿(mào)網(wǎng)站制作,南雄網(wǎng)站建設(shè)費(fèi)用合理。

最近想給項(xiàng)目添加一個(gè)簡(jiǎn)單的分布式請(qǐng)求跟蹤功能,從前端發(fā)起請(qǐng)求到網(wǎng)關(guān),再?gòu)木W(wǎng)關(guān)調(diào)用 Spring Cloud  的微服務(wù),這些過(guò)程中希望能從日志中看到一個(gè)分布式 ID 的鏈路,通過(guò)請(qǐng)求的 ID 可以追蹤整一條鏈路,方便問(wèn)題的排查。

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

主要包括幾個(gè)步驟:

  • 從前端生成請(qǐng)求 ID 并加入請(qǐng)求頭帶入網(wǎng)關(guān)

  • 網(wǎng)關(guān)通過(guò) WebFilter 攔截并加入 MDC 中,在 log 中輸出

  • 在 Feign 和 RequestTemplate 中將請(qǐng)求 ID 在帶到 HTTP 的 Header 中微服務(wù)傳遞

  • 各個(gè)微服務(wù)同樣通過(guò) WebFilter 實(shí)現(xiàn)攔截并加入 MDC,在 log 中輸出

MDC

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

MDC 的關(guān)鍵操作:

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

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

  • 將 MDC 中內(nèi)容打印到日志中:%X{key}

新增 TraceId 工具類

先新增一個(gè) TraceIdUtils 工具類,用于定義 TRACE_ID 的常量值以及設(shè)置及生成 TRACE_ID  的方法,后續(xù)代碼中都是通過(guò)這個(gè)估計(jì)類進(jìn)行操作。

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);     }      /**      * 設(shè)置 traceId      */     public static void setTraceId(String traceId) {         // 如果參數(shù)為空,則生成新 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;     } }

通過(guò) WebFilter 添加 TraceId 過(guò)濾器

新增一個(gè) GenericFilterBean ,從請(qǐng)求頭中獲取 TraceIdUtils.TRACE_ID  對(duì)應(yīng)的值,該值在前端發(fā)起請(qǐng)求或者微服務(wù)之間傳遞都會(huì)帶上,如果沒(méi)有,則 TraceIdUtils.setTraceId 會(huì)生成一個(gè)。

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);         // 執(zhí)行后續(xù)過(guò)濾器         filterChain.doFilter(request, response);     } }

不要忘記在 SpringBoot 的啟動(dòng)類加上 @ServletComponentScan 注解,否則自定義的 Filter 無(wú)法生效。其中  “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

因?yàn)?@FeignClient 的代理類在執(zhí)行的時(shí)候,會(huì)去使用使用到 Spring 上下文的  RequestInterceptor,所以自定義自己的攔截器,然后注入到 Spring 上下文中,這樣就可以在請(qǐng)求的上下文中添加自定義的請(qǐng)求頭。

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

還有一部分請(qǐng)求是通過(guò) RestTemplate 發(fā)起的,之前我們是自己實(shí)現(xiàn)了 RestTemplateConfig  的配置類,這次在相關(guān)的配置上添加:

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

至此,鏈路上的 TraceId 添加已經(jīng)完成,剩下的就是在日志中打印出來(lái)了。

修改 Log4j2 的 layout 格式

修改日志的layout格式,將MDC中的traceId打印出來(lái):

  )}%n"/>    )}%n"/>

上述就是小編為大家分享的微服務(wù)如何實(shí)現(xiàn)簡(jiǎn)單的分布式日志追蹤了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


網(wǎng)頁(yè)標(biāo)題:微服務(wù)如何實(shí)現(xiàn)簡(jiǎn)單的分布式日志追蹤
鏈接地址:http://weahome.cn/article/jhoeei.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部