Dubbo日誌鏈路追蹤TraceId選型
一、目的
開發排查系統問題用得最多的手段就是檢視系統日誌,但是在分散式環境下使用日誌定位問題還是比較麻煩,需要藉助 全鏈路追蹤ID
把上下文串聯起來,本文主要分享基於 Spring Boot
+ Dubbo
框架下 日誌鏈路追蹤ID
的實現方案選型思路。
目前大多數分散式追蹤系統的思想模型都來自 Google’s Dapper 論文
全鏈路追蹤的核心思想:
- 為每條請求都單獨分配一個唯一的
traceId
用來標識一條請求鏈路,該traceId
會貫穿整個請求處理過程的所有服務 - 每個服務/執行緒都擁有自己的
spanId
標識,代表請求的其中一段處理步驟 - 一個請求包含一個
traceId
和一個或多個spanId
日誌全鏈路追蹤 就是在每條系統日誌裡都新增顯示
traceId
和spanId
資訊
二、方案選型
2.1. 方案一(apm-toolkit)
這是 SkyWalking
的一個日誌外掛,透過這個外掛可以在日誌中輸出traceId
2.1.1. 使用方式
配置依賴,在 pom 檔案中新增以下內容
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>8.1.0</version>
</dependency>
配置日誌模板,修改 logback-spring.xml
檔案中 Appender
元素的 encoder
為以下內容
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%tid] [%thread] %-5level %logger{35} - %msg%n</pattern>
</layout>
</encoder>
ps: pattern 中的內容按需修改,其中的 %tid 就是相當於 traceId,預設 TID:N/A,當有請求呼叫時會生成並顯示 traceId
2.1.2. 總結
-
優點:無需編碼,業務無入侵,可與
SkyWalking
的圖形化介面中使用該ID快速定位各種介面的呼叫關係。 -
缺點:強耦合
SkyWalking
才能生效- 必須新增sk的
javaagent
- 必須部署
SkyWalking
服務端
- 必須新增sk的
2.2. 方案二(sleuth)
Sleuth
是 Spring Cloud
的元件之一,它為 Spring Cloud
實現了一種分散式追蹤解決方案,相容Zipkin,HTrace與其他日誌追蹤系統
2.2.1. 使用方式
配置父依賴,在 pom 檔案中新增以下內容管理版本號
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth</artifactId>
<version>2.2.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencyManagement>
配置依賴,在 pom 檔案中新增以下內容
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
適配dubbo,要讓 sleuth
支援 dubbo
框架,需要增加以下兩個步驟:
首先新增 dubbo 的外掛依賴
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-dubbo-rpc</artifactId>
<version>5.12.6</version>
</dependency>
配置 dubbo 過濾器
dubbo:
provider:
filter: tracing
consumer:
filter: tracing
配置日誌模板,修改 logback-spring.xml
檔案中 Appender
元素的 encoder
為以下內容
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{X-B3-TraceId},%X{X-B3-SpanId}] [%thread] %-5level %logger{35} - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
ps: pattern 中的內容按需修改,其中的 %X{X-B3-TraceId} 為 traceId,%X{X-B3-SpanId} 為 spanId
2.2.2. 總結
-
優點:業務無入侵,有豐富的外掛進行擴充套件包括定時任務、MQ等。
-
缺點:
brave-instrumentation-dubbo-rpc
不支援dubbo 2.7.x
需要自行開發外掛。
2.3. 方案三(自研)
2.3.1. 無入侵增加 traceId
使用 Logback
的 MDC
機制,在日誌模板中加入 traceId
標識,取值方式為 %X{traceId}
- 系統入口(api閘道器)建立
traceId
的值 - 使用
MDC
儲存traceId
- 修改
logback
配置檔案模板格式新增標識%X{traceId}
MDC(Mapped Diagnostic Context,對映除錯上下文)是 log4j 和 logback 提供的一種方便在多執行緒條件下記錄日誌的功能。
2.3.2. 跨執行緒傳遞
解決 traceId
跨執行緒丟失問題
由於 MDC
內部使用的是 ThreadLocal
所以只有本執行緒才有效,子執行緒和下游的服務 MDC
裡的值會丟失;
需要解決 Spring
的各種執行緒池與非同步方法的父子執行緒間傳遞。
解決思路:重寫一個 MDCAdapter
使用阿里的 TransmittableThreadLocal
替換原來的 ThreadLocal
物件,解決各種執行緒池(ExecutorService
/ ForkJoinPool
/ TimerTask
)父子程式傳值問題。
需要使用
TtlRunnable
和TtlCallable
來修飾傳入執行緒池的Runnable
和Callable
2.3.3. 跨程式傳遞
解決 traceId
跨程式丟失問題
dubbo服務 使用 org.apache.dubbo.rpc.Filter
建立一個過濾器進行 traceId
傳遞
- 服務消費者:負責傳遞鏈路追蹤 ID
- 服務提供者:負責接收 ID 並儲存到
MDC
中
2.3.4. 總結
-
優點:業務無入侵,最小依賴,擴充套件靈活,適配性強。
-
缺點:需要自行實現,有大量的開發工作量。
三、方案總結
方案 | 開發工作量 | 可維護性 | 入侵性 | 效能 |
---|---|---|---|---|
apm-toolkit | 無 | 低 | 業務無入侵 | 中 |
sleuth | 中 | 中 | 業務無入侵 | 中 |
自研 | 高 | 高 | 業務無入侵 | 高 |
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/758/viewspace-2826343/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 日誌追蹤:log增加traceId
- Spring中使用MDC和traceId實現日誌鏈路追蹤Spring
- 日誌收集和鏈路追蹤:skywalking
- 註解列印日誌和資料鏈路追蹤
- 日誌追蹤
- 從 1.5 開始搭建一個微服務框架——日誌追蹤 traceId微服務框架
- 透過鉤子函式+Traceid實現Flask鏈路追蹤函式Flask
- .NET Core 中的日誌與分散式鏈路追蹤分散式
- dubbo分散式應用中使用zipkin做鏈路追蹤分散式
- go的鏈路追蹤Go
- 基於SLF4J MDC機制實現日誌的鏈路追蹤
- Java應用層資料鏈路追蹤(附優雅列印日誌姿勢)Java
- springboot+MDCAdapter自定義starter實現日誌全鏈路追蹤Spring BootAPT
- Spring Cloud 鏈路追蹤SpringCloud
- skywalking鏈路追蹤
- 微服務整合Spring Cloud Zipkin實現鏈路追蹤並整合Dubbo微服務SpringCloud
- Spring cloud 整合 SkyWalking 實現效能監控、鏈路追蹤、日誌收集SpringCloud
- 通過日誌審計追蹤外部***
- 分散式鏈路追蹤技術分散式
- Spring Cloud Sleuth 鏈路追蹤SpringCloud
- Go 鏈路追蹤入門 OpentelemetryGo
- 基於SLF4J的MDC機制和Dubbo的Filter機制,實現分散式系統的日誌全鏈路追蹤Filter分散式
- 分散式鏈路追蹤的利器——Zipkin分散式
- golang 接入鏈路追蹤(opentracing)Golang
- zipkin分散式鏈路追蹤介紹分散式
- 輕量級的分散式日誌追蹤利器,十分鐘即可接入,從此日誌追蹤無難事分散式
- log4j MDC實現日誌追蹤
- Go - 實現專案內鏈路追蹤Go
- BOS分散式鏈路追蹤產品揭秘分散式
- 微服務鏈路追蹤元件 SkyWalking微服務元件
- go-kit微服務:服務鏈路追蹤Go微服務
- AsyncLocal<T>在鏈路追蹤中的應用
- Jaeger Client Go 鏈路追蹤|入門詳解clientGo
- Go - 實現專案內鏈路追蹤(二)Go
- 【剖析 | SOFARPC 框架】系列之鏈路追蹤剖析RPC框架
- net core 微服務框架 Viper 呼叫鏈路追蹤微服務框架
- (16)go-micro微服務jaeger鏈路追蹤Go微服務
- 日誌與追蹤的完美融合:OpenTelemetry MDC 實踐指南