Dubbo日志鏈路追蹤TraceId選型

封面.png

一餐屎、目的

開發(fā)排查系統(tǒng)問題用得最多的手段就是查看系統(tǒng)日志场靴,但是在分布式環(huán)境下使用日志定位問題還是比較麻煩,需要借助 全鏈路追蹤ID 把上下文串聯(lián)起來忠怖,本文主要分享基于 Spring Boot + Dubbo 框架下 日志鏈路追蹤ID 的實現方案選型思路呢堰。

?

目前大多數分布式追蹤系統(tǒng)的思想模型都來自 Google's Dapper 論文

depper.png

全鏈路追蹤的核心思想:

  • 為每條請求都單獨分配一個唯一的 traceId 用來標識一條請求鏈路,該 traceId 會貫穿整個請求處理過程的所有服務
  • 每個服務/線程都擁有自己的 spanId 標識凡泣,代表請求的其中一段處理步驟
  • 一個請求包含一個 traceId 和一個或多個 spanId

日志全鏈路追蹤 就是在每條系統(tǒng)日志里都添加顯示 traceIdspanId 信息

日志鏈路追蹤.png

?

二枉疼、方案選型

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. 總結

  • 優(yōu)點:無需編碼褪测,業(yè)務無入侵,可與 SkyWalking 的圖形化界面中使用該ID快速定位各種接口的調用關系潦刃。

  • 缺點:強耦合 SkyWalking 才能生效

    • 必須添加sk的 javaagent
    • 必須部署 SkyWalking 服務端

?

2.2. 方案二(sleuth)

SleuthSpring Cloud 的組件之一侮措,它為 Spring Cloud 實現了一種分布式追蹤解決方案,兼容Zipkin乖杠,HTrace與其他日志追蹤系統(tǒng)

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. 總結

  • 優(yōu)點:業(yè)務無入侵,有豐富的插件進行擴展包括定時任務汛兜、MQ等巴粪。

  • 缺點brave-instrumentation-dubbo-rpc 不支持 dubbo 2.7.x 需要自行開發(fā)插件。

?

2.3. 方案三(自研)

2.3.1. 無入侵增加 traceId

使用 LogbackMDC 機制粥谬,在日志模板中加入 traceId 標識肛根,取值方式為 %X{traceId}

  1. 系統(tǒng)入口(api網關)創(chuàng)建 traceId 的值
  2. 使用 MDC 保存 traceId
  3. 修改 logback 配置文件模板格式添加標識 %X{traceId}

MDC(Mapped Diagnostic Context,映射調試上下文)是 log4j 和 logback 提供的一種方便在多線程條件下記錄日志的功能漏策。

?

2.3.2. 跨線程傳遞

解決 traceId 跨線程丟失問題

mdc源碼.png

由于 MDC 內部使用的是 ThreadLocal 所以只有本線程才有效派哲,子線程和下游的服務 MDC 里的值會丟失;

需要解決 Spring 的各種線程池與異步方法的父子線程間傳遞掺喻。

解決思路:重寫一個 MDCAdapter 使用阿里的 TransmittableThreadLocal 替換原來的 ThreadLocal 對象芭届,解決各種線程池(ExecutorService / ForkJoinPool / TimerTask)父子進程傳值問題。

需要使用 TtlRunnableTtlCallable 來修飾傳入線程池的 RunnableCallable

?

2.3.3. 跨進程傳遞

解決 traceId 跨進程丟失問題

dubbo服務 使用 org.apache.dubbo.rpc.Filter 創(chuàng)建一個過濾器進行 traceId 傳遞

  • 服務消費者:負責傳遞鏈路追蹤 ID
  • 服務提供者:負責接收 ID 并保存到 MDC

?

2.3.4. 總結

  • 優(yōu)點:業(yè)務無入侵感耙,最小依賴褂乍,擴展靈活,適配性強即硼。

  • 缺點:需要自行實現逃片,有大量的開發(fā)工作量。

?

三只酥、方案總結

方案 開發(fā)工作量 可維護性 入侵性 性能
apm-toolkit 業(yè)務無入侵
sleuth 業(yè)務無入侵
自研 業(yè)務無入侵
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末褥实,一起剝皮案震驚了整個濱河市呀狼,隨后出現的幾起案子,更是在濱河造成了極大的恐慌损离,老刑警劉巖哥艇,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異僻澎,居然都是意外死亡她奥,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門怎棱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人绷跑,你說我怎么就攤上這事拳恋。” “怎么了砸捏?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵谬运,是天一觀的道長。 經常有香客問我垦藏,道長梆暖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任掂骏,我火速辦了婚禮轰驳,結果婚禮上,老公的妹妹穿的比我還像新娘弟灼。我一直安慰自己级解,他們只是感情好,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布田绑。 她就那樣靜靜地躺著勤哗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪掩驱。 梳的紋絲不亂的頭發(fā)上芒划,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天,我揣著相機與錄音欧穴,去河邊找鬼民逼。 笑死,一個胖子當著我的面吹牛苔可,可吹牛的內容都是我干的缴挖。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼焚辅,長吁一口氣:“原來是場噩夢啊……” “哼映屋!你這毒婦竟也來了苟鸯?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤棚点,失蹤者是張志新(化名)和其女友劉穎早处,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體瘫析,經...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡砌梆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了贬循。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咸包。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖杖虾,靈堂內的尸體忽然破棺而出烂瘫,到底是詐尸還是另有隱情,我是刑警寧澤奇适,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布坟比,位于F島的核電站,受9級特大地震影響嚷往,放射性物質發(fā)生泄漏葛账。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一皮仁、第九天 我趴在偏房一處隱蔽的房頂上張望籍琳。 院中可真熱鬧,春花似錦贷祈、人聲如沸巩割。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宣谈。三九已至,卻和暖如春键科,著一層夾襖步出監(jiān)牢的瞬間闻丑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工勋颖, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留嗦嗡,地道東北人。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓饭玲,卻偏偏與公主長得像侥祭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345