【服務日志鏈路追蹤】

MDC+InheritableThreadLocal和spring cloud sleuth

在微服務架構中,日志鏈路追蹤(Logback + Distributed Tracing) 是一個關鍵需求,主要用于跟蹤請求在不同服務間的調用鏈路,便于排查問題。常見的實現方案有兩種:

手動方案(MDC + InheritableThreadLocal)

自動化方案(Spring Cloud Sleuth + Zipkin/Jaeger)

下面從 Logback 日志集成 的角度,對比這兩種方案的實現方式、優缺點及適用場景。

  1. 手動方案:MDC + InheritableThreadLocal
    核心組件
    MDC(Mapped Diagnostic Context)

Logback 提供的線程本地存儲,用于存放日志變量(如 traceId)。

日志輸出時自動攜帶 MDC 中的字段(需配置 %X{traceId})。

InheritableThreadLocal

解決異步線程(如線程池、@Async)無法繼承 MDC 的問題。

實現步驟
(1) 定義 TraceContext(管理 traceId)

public class TraceContext {private static final InheritableThreadLocal<String> TRACE_ID = new InheritableThreadLocal<>();public static void setTraceId(String traceId) {TRACE_ID.set(traceId);MDC.put("traceId", traceId); // 存入 MDC,Logback 自動輸出}public static String getTraceId() {return TRACE_ID.get();}public static void clear() {TRACE_ID.remove();MDC.remove("traceId");}
}

(2) 攔截器設置 traceId(HTTP 請求入口)

public class TraceInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {String traceId = request.getHeader("X-Trace-Id") != null ? request.getHeader("X-Trace-Id") : UUID.randomUUID().toString();TraceContext.setTraceId(traceId);return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {TraceContext.clear(); // 防止內存泄漏}
}

(3) Logback 配置(輸出 traceId)

<!-- logback-spring.xml -->
<configuration><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{HH:mm:ss.SSS} [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n</pattern></encoder></appender><root level="INFO"><appender-ref ref="STDOUT" /></root>
</configuration>

日志示例:

14:25:30.456 [http-nio-8080-exec-1] [abc123] INFO  com.example.demo.Controller - Request received

(4) 異步線程支持(線程池需額外處理)

// 普通線程
new Thread(() -> {log.info("Async task"); // 能繼承 traceId
}).start();// 線程池需使用 TransmittableThreadLocal(阿里開源庫)
ExecutorService executor = Executors.newCachedThreadPool();
executor.submit(() -> {log.info("ThreadPool task"); // 默認會丟失 traceId!
});

在這里插入圖片描述
TransmittableThreadLocal vs InheritableThreadLocal
在這里插入圖片描述

  1. 自動化方案:Spring Cloud Sleuth + Logback
    核心組件
    Spring Cloud Sleuth

自動生成 traceId 和 spanId,并通過 MDC 輸出到日志。

支持 HTTP(Feign/RestTemplate)、MQ(Kafka/RabbitMQ)、gRPC 等自動傳播。

Logback 集成

Sleuth 自動填充 MDC,無需手動管理。

實現步驟
(1) 引入依賴

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<!-- 可選:上報到 Zipkin -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>

(2) Logback 配置(自動攜帶 traceId)

<configuration><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{HH:mm:ss.SSS} [%thread] [%X{traceId:-}] %-5level %logger{36} - %msg%n</pattern></encoder></appender><root level="INFO"><appender-ref ref="STDOUT" /></root>
</configuration>

日志示例(Sleuth 自動填充 traceId 和 spanId):

<configuration><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{HH:mm:ss.SSS} [%thread] [%X{traceId:-}] %-5level %logger{36} - %msg%n</pattern></encoder></appender><root level="INFO"><appender-ref ref="STDOUT" /></root>
</configuration>

(3) 跨服務調用(自動傳播 traceId)
HTTP(Feign):自動添加 X-B3-TraceId Header。

MQ(Kafka):消息頭自動攜帶追蹤信息。

在這里插入圖片描述

  1. 對比總結
    在這里插入圖片描述

  2. 推薦選擇
    簡單項目:使用 MDC + InheritableThreadLocal(或 TransmittableThreadLocal)。

微服務架構:直接上 Spring Cloud Sleuth(或 OpenTelemetry),減少維護成本。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/76609.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/76609.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/76609.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Kafka+Zookeeper從docker部署到spring boot使用完整教程

文章目錄 一、Kafka1.Kafka核心介紹&#xff1a;?核心架構?核心特性?典型應用 2.Kafka對 ZooKeeper 的依賴&#xff1a;3.去 ZooKeeper 的演進之路&#xff1a;注&#xff1a;&#xff08;本文采用ZooKeeper3.8 Kafka2.8.1&#xff09; 二、Zookeeper1.核心架構與特性2.典型…

JUC系列JMM學習之隨筆

JUC: JUC 是 Java 并發編程的核心工具包,全稱為 Java Util Concurrent,是 java.util.concurrent 包及其子包的簡稱。它提供了一套強大且高效的并發編程工具,用于簡化多線程開發并提高性能。 CPU核心數和線程數的關系:1核處理1線程(同一時間單次) CPU內核結構: 工作內…

The Rust Programming Language 學習 (九)

泛型 每一個編程語言都有高效處理重復概念的工具。在 Rust 中其工具之一就是 泛型&#xff08;generics&#xff09;。泛型是具體類型或其他屬性的抽象替代。我們可以表達泛型的屬性&#xff0c;比如他們的行為或如何與其他泛型相關聯&#xff0c;而不需要在編寫和編譯代碼時知…

藍橋杯 混乘數字

問題描述 混乘數字的定義如下&#xff1a; 對于一個正整數 n&#xff0c;如果存在正整數 a 和 b&#xff0c;使得&#xff1a; n a b且 a 與 b 的十進制數位中每個數字出現的次數之和&#xff0c;與 n 中對應數字出現的次數相同&#xff0c;則稱 n 為混乘數字。 示例 對于…

CExercise04_1位運算符_2 定義一個函數判斷給定的正整數是否為2的冪

題目&#xff1a; 給定一個正整數&#xff0c;請定義一個函數判斷它是否為2的冪(1, 2, 4, 8, 16, …) 分析&#xff1a; &#xff1a; 代碼 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdbool.h>/* 給定一個正整數&#xff0c;請定義一個函數…

SSL證書不可信的原因有哪些?(國科云)

SSL證書用于在客戶端和服務器端之間建立一條加密通道&#xff0c;確保數據在傳輸過程中的安全性和完整性。然而&#xff0c;在實際應用中&#xff0c;我們有時會遇到SSL證書不可信的情況&#xff0c;嚴重影響了用戶對網站的信任度。那么&#xff0c;SSL證書不可信的原因究竟有哪…

[王陽明代數講義]琴語言類型系統工程特性

琴語言類型系統工程特性 層展物理學組織實務與藝術與琴生生.物機.械科.技工.業研究.所軟凝聚態物理開發工具包社會科學氣質砥礪學人生意氣場社群成員魅力場與心氣微積分社會關系力學 意氣實體過程圖論信息編碼&#xff0c;如來碼導引 注意力機制道裝Transformer架構的發展標度律…

自抗擾ADRC之二階線性擴展狀態觀測器(LESO)推導

1.龍伯格觀測器 實際工程應用中&#xff0c;狀態變量有時難以使用傳感器直接測量&#xff0c;在這種情況下&#xff0c;使用狀態觀測器估計系統實際狀態是非常常見的做法。最出名的狀態觀測器當屬龍伯格博士在1971年發表于TAC的An Introduction to Observer[1]一文中提出的基于…

從頭開發一個Flutter插件(二)高德地圖定位插件

開發基于高德定位SDK的Flutter插件 在上一篇文章里具體介紹了Flutter插件的具體開發流程&#xff0c;從創建項目到發布。接下來將為Flutter天氣項目開發一個基于高德定位SDK的Flutter定位插件。 申請key 首先進入高德地圖定位SDK文檔內下載定位SDK&#xff0c;并按要求申請A…

分布式鎖之redis6

一、分布式鎖介紹 之前我們都是使用本地鎖&#xff08;synchronize、lock等&#xff09;來避免共享資源并發操作導致數據問題&#xff0c;這種是鎖在當前進程內。 那么在集群部署下&#xff0c;對于多個節點&#xff0c;我們要使用分布式鎖來避免共享資源并發操作導致數據問題…

ubuntu中使用安卓模擬器

本文這里介紹 使用 android studio Emulator &#xff0c; 當然也有 Anbox (Lightweight)&#xff0c; Waydroid (Best for Full Android Experience), 首先確保自己安裝了 android studio &#xff1b; sudo apt update sudo apt install openjdk-11-jdk sudo snap install…

二語習得理論(Second Language Acquisition, SLA)如何學習英語

二語習得理論&#xff08;Second Language Acquisition, SLA&#xff09;是研究學習者如何在成人或青少年階段學習第二語言&#xff08;L2&#xff09;的理論框架。該理論主要關注語言習得過程中的認知、社會和文化因素&#xff0c;解釋了學習者如何從初學者逐漸變得流利并能夠…

WinDbg. From A to Z! 筆記(下)

原文鏈接: WinDbg. From A to Z! 文章目錄 使用WinDbg臨界區相關命令示例 -- 查看臨界區其他有用的命令 WinDbg中的偽寄存器自動偽寄存器 WinDbg中的表達式其他操作默認的表達式計算方式 WinDbg中的重命名調試器命令語言編程控制流命令程序執行 WinDbg 遠程調試事件監控WinDbg …

RainbowDash 的旅行

D RainbowDash 的旅行 - 第七屆校賽正式賽 —— 補題 題目大意&#xff1a; 湖中心有一座島&#xff0c;湖的外圍有 m m m 間木屋&#xff08;圍繞小島&#xff09; &#xff0c;第 i i i 間木屋和小島之間有 a i a_i ai? 座 A A A 類橋&#xff0c; b i b_i bi? 座 B …

MySQL-SQL-DDL語句、表結構創建語句

一.SQL SQL&#xff1a;一門操作關系型數據庫的編程語言&#xff0c;定義操作所有關系型數據庫的統一標準 二. DDL-數據庫 1. 查詢所有數據庫 命令&#xff1a;show databases; 2. 查詢當前數據庫 命令&#xff1a;select database(); 3. 創建數據庫 命令&#xff1a;create da…

Sora結構猜測

方案&#xff1a;VAE Encoder&#xff08;視頻壓縮&#xff09; -> Transform Diffusion &#xff08;從視頻數據中學習分布&#xff0c;并根據條件生成新視頻&#xff09; -> VAE Decoder &#xff08;視頻解壓縮&#xff09; 從博客出發&#xff0c;經過學術Survey&am…

TortoiseSVN設置忽略清單

1.TortoiseSVN > Properties&#xff08;如果安裝了 TortoiseSVN&#xff09;。 2. 在彈出的屬性窗口中&#xff0c;點擊 New > Other。 4. 在 Property name 中輸入 svn:ignore 。 5. 在 Property value 中輸入要忽略的文件夾或文件名稱&#xff0c;例如&#xff1a; #…

深入解析Java哈希表:從理論到實踐

哈希表&#xff08;Hash Table&#xff09;是計算機科學中最重要的數據結構之一&#xff0c;也是Java集合框架的核心組件。本文將以HashMap為切入點&#xff0c;深入剖析Java哈希表的實現原理、使用技巧和底層機制。 一、哈希表基礎原理 1. 核心概念 鍵值對存儲&#xff1a;通…

leetcode:1582. 二進制矩陣中的特殊位置(python3解法)

難度&#xff1a;簡單 給定一個 m x n 的二進制矩陣 mat&#xff0c;返回矩陣 mat 中特殊位置的數量。 如果位置 (i, j) 滿足 mat[i][j] 1 并且行 i 與列 j 中的所有其他元素都是 0&#xff08;行和列的下標從 0 開始計數&#xff09;&#xff0c;那么它被稱為 特殊 位置。 示…

《數字圖像處理》教材尋找合作者

Rafael Gonzalez和Richard Woods所著的《數字圖像處理》關于濾波器的部分幾乎全錯&#xff0c;完全從零開始寫&#xff0c;困難重重。關于他的問題已經描述在《數字圖像處理&#xff08;面向新工科的電工電子信息基礎課程系列教材&#xff09;》。 現尋找能夠共同討論、切磋、…