螞蟻金服分佈式鏈路跟蹤組件 SOFATracer 總覽 | 剖析

2019新春支付寶紅包技術大揭祕在線峯會將於03-07日開始,點擊這裏報名屆時即可參與大牛互動。

SOFA Scalable Open Financial Architecture
是螞蟻金服自主研發的金融級分佈式中間件,包含了構建金融級雲原生架構所需的各個組件,是在金融場景裏錘鍊出來的最佳實踐。 SOFATracer
是一個用於分佈式系統調用跟蹤的組件,通過統一的 TraceId
將調用鏈路中的各種網絡調用情況以日誌的方式記錄下來,以達到透視化網絡調用的目的,這些鏈路數據可用於故障的快速發現,服務治理等。 本文爲《剖析
| SOFATracer 框架》第一篇。《剖析 | SOFATracer 框架》系列由 SOFA
團隊和源碼愛好者們出品,項目代號:<SOFA:TracerLab/>,文章尾部有參與方式,歡迎同樣對源碼熱情的你加入。

0. 前言

在單體應用時代,我們不需要花費時間去關心調用鏈路這個東西。

但是鏈路跟蹤不僅僅是在分佈式場景下纔會有,即使是單體應用,同樣也會存在調用鏈路。

例如,我們把應用中的每個服務接口作爲一個鏈路節點,那麼從請求進來到返回響應,把這個過程中多歷經的所有的方法接口串聯起來,就能組成一條完整的鏈路,如下圖所示:
在這裏插入圖片描述

對於單體應用而言,如果訪問一個資源沒有成功,那麼我們可以很快的鎖定是哪一臺機器,然後通過查詢這臺機器上的日誌就能定位問題。

但是在微服務體系架構下,這種方式會顯得非常無力。對於一個稍具規模的應用來說,一次請求可能會跨越相當多的服務節點,在這種情況下,如果一個請求沒有得到成功的響應,就不能確定到底是哪個節點出了問題。
在這裏插入圖片描述

因此在面對這種複雜的大規模分佈式集羣來實現的服務體系來說,就需要一些可以幫助理解各個應用的線上調用行爲、並可以分析遠程調用的組件。

基於上述背景,螞蟻金服開源了基於 OpenTracing 規範 (http://opentracing.io/documen...)實現的 SOFATracer 分佈式鏈路跟蹤組件,爲實施大規模服務化體系架構場景下提供了鏈路跟蹤的解決方案。

在介紹 SOFATracer 之前,先來了解一下 Opentracing 規範。

1. Opentracing 簡介

首先來解釋下 OpenTracing 是什麼OpenTracing 致力於爲分佈式跟蹤創建更標準化的API和工具,它由完整的API規範、實現該規範的框架、庫以及項目文檔組成。

OpenTracing 提供了一套平臺無關、廠商無關的 API,這樣不同的組織或者開發人員就能夠更加方便的添加或更換追蹤系統的實現。 OpenTracing API 中的一些概念和術語,在不同的語言環境下都是共享的。

1.1 數據模型

Opentracing 規範中,一條 trace 鏈路是由多個與之關聯的 span 組成,一條鏈路整體可以看做是一張有向無環圖,各個span之間的邊緣關係被稱之爲“References”。下面是官方提供的示例:
在這裏插入圖片描述

如果以時間軸維度來看的話,也可以表現爲下面的形式(官方示例):
在這裏插入圖片描述

  • root span : 當前鏈路中的第一個 span
  • ChildOf 和 FollowFrom 是目前被定義的兩種 References

類型 ChildOf : 父 Span 以某種身份依賴於子Span
FollowFrom : 父 Span 不以任何方式依賴子

   Span

但是爲了簡化 span 之間的這種依賴關係,在具體實現時通常會將具有嵌套關係的作爲 ChildOf,平行執行的作爲FollowFrom,比如:

a. ChildOf 示例

在 methodA 中調用了 method B :

methodA(){      // spanA start
  methodB();   
}           // spanA finish
methodB(){      // spanB start
}           // spanB finish

產生的 span 在時間維度上展現的視角如下:
在這裏插入圖片描述

這種關係一般會表示爲 SpanB ChildOf SpanA 。

b. FollowFrom 示例

method 方法中,methodA 執行之後 methodB 執行 :

method(){
  methodA();
  methodB();
}

產生的 span 在時間維度上展現的視角如下:

在這裏插入圖片描述

這種關係一般會表示爲 SpanB FollowFrom SpanA 。

1.2 API

Opentracing API 是對分佈式鏈路中涉及到的一些列操作的高度抽象集合。Opentracing 中將所有核心的組件都聲明爲接口,例如 Tracer、Span、SpanContext、Format(高版本中還包括 Scope 和 ScopeManager)等。SOFATracer 使用的版本是 0.22.0 ,主要是對 Tracer、Span、SpanContext 三個概念模型的實現。下面就針對這三個組件結合 SOFATracer 來分析。

1.3 SOFATracer 標準實現

下圖爲 SOFATracer 中對於這三個核心接口實現的類圖結構:
在這裏插入圖片描述

由於篇幅原因,下面的介紹過程中一些點不會展開說明,有興趣的同學可以自行官網查看完整的 OpenTracing-api 規範 (https://opentracing.io/specif...)。

a. Tracer & SOFATracer

Tracer 是一個簡單、廣義的接口,它的作用就是構建 span 和傳輸 span 。核心接口列表如下:
在這裏插入圖片描述

SofaTracer 實現了 Tracer 接口,並擴展了採樣、數據上報等能力。

b. Span & SOFATracerSpan

Span 是一個跨度單元,在實際的應用過程中,Span 就是一個完整的數據包,其包含的就是當前節點所需要上報的數據。核心接口列表如下:
在這裏插入圖片描述

關於tags和log的解釋:如果把從進入公司到離開公司這段時間作爲一個 span,那麼 tags
裏面可以是你寫的代碼,你喝的水,甚至你講過的話;log 則更關注某個時刻的事,比如在12:00 去吃了個飯,在15:00 開了個會。 如果說
tags 裏面都是和公司有關的,那麼 Baggage 裏面則不僅僅是侷限於你在公司的事,比如你口袋裏的手機。

SofaTracerSpan 在實現 Span 接口,並擴展了對 Reference、tags、線程異步處理以及插件擴展中所必須的 logType 和產生當前 span 的 Tracer 類型等處理的能力。

c. SpanContext & SOFATracerSpanContext

SpanContext 對於 OpenTracing 實現是至關重要的,通過 SpanContext 可以實現跨進程的鏈路透傳,並且可以通過 SpanContext 中攜帶的信息將整個鏈路串聯起來。

官方文檔中有這樣一句話:“在 OpenTracing 中,我們強迫 SpanContext 實例成爲不可變的,以避免 Span
在finish 和 reference 操作時會有複雜的生命週期問題。” 這裏是可以理解的,如果 SpanContext
在透傳過程中發生了變化,比如改了 tracerId,那麼就可能導致鏈路出現斷缺。

SpanContext 中只有一個接口:
在這裏插入圖片描述

SofaTracerSpanContext 實現了 SpanContext 接口,擴展了構建 SpanContext、序列化 baggageItems 以及SpanContext等新的能力,除此之外,SpanContext 在跨進行透傳時攜帶的信息進行了規範:
在這裏插入圖片描述

2. SOFATracer 擴展

爲了滿足在複雜場景下的鏈路跟蹤需求,SOFATracer 在 Opentracing 規範基礎上又提供了豐富的擴展能力。

2.1 SOFATracer 架構及功能擴展

在這裏插入圖片描述

SOFATracer 基於 OpenTracing 規範(https://opentracing.io/specif...)實現,並且通過 Disruptor (https://github.com/LMAX-Excha...

  • 基於 SLF4J 的 MDC 擴展能力

應用在通過面向日誌編程接口 SLF4J 打印應用日誌時,可以只在對應的日誌實現配置文件的 PatternLayout 中添加相應的參數即可,如添加 [%X{SOFA-TraceId},%X{SOFA-SpanId}] ,那麼應用日誌就可以在發生鏈路調用時打印出相應的 TraceId 和 SpanId ,而無論應用具體的日誌實現是 Logback、Log4j2 或者 Log4j。關於這部分的實現原理,期待大家一起編寫,領取方式見文末。

  • SOFATracer 的埋點機制

SOFATracer 目前僅提供了基於自身 API 埋點的方式。SOFATracer 中所有的插件均需要實現自己的 Tracer 實例,如 Mvc 的 SpringMvcTracer 、HttpClient 的 HttpClientTracer 等,如下圖所示:
在這裏插入圖片描述

SOFATracer 將不同的擴展組件分爲 AbstractClientTracer 和 AbstractServerTracer,再通過AbstractClientTracer 和 AbstractServerTracer 衍生出具體的組件 Tracer 實現。這種方式的好處在於,所有的插件實現均有 SOFATracer 本身來管控,對於不同的組件可以輕鬆的實現差異化和定製化。

但是爲了能夠擁抱社區,我們在後續的版本中將會提供基於 Opentracing API 的埋點擴展實現,從而實現與 opentracing-contrib 的無縫對接。基於 Opentracing API 的插件埋點方案如下圖所示:
在這裏插入圖片描述

關於 SOFATracer 基於特有 API 埋點的實現以及如何實現對接 OT-api 埋點,期待大家一起編寫,領取方式見文末。

  • SOFATracer 的數據上報機制

SOFATracer 中並沒有將不同的 Reporter 設計成不同的策略,然後根據不同的策略來實現具體的上報操作,而是使用了一種類似組合的方式,並且在執行具體上報的流程中通過參數來調控是否執行具體的上報。
在這裏插入圖片描述

從流程圖中可以看到,此過程中涉及到了三個上報點,首先是上報到 zipkin,後面是落盤;在日誌記錄方面,SOFATracer 中爲不同的組件均提供了獨立的日誌空間,除此之外,SOFATracer 在鏈路數據採集時提供了兩種不同的日誌記錄模式:摘要日誌和統計日誌,這對於後續構建一些如故障的快速發現、服務治理等管控端提供了強大的數據支撐。關於數據上報,期待大家一起編寫,領取方式見文末。

  • SOFATracer 的採樣機制

對於鏈路中的數據,並非所有的數據都是值得關注的。一方面是可以節約磁盤空間,另一方面可以將某些無關數據直接過濾掉。基於此,SOFATracer 提供了鏈路數據採樣能力。目前我們提供了兩種策略,一種是基於固定比率的採樣,另一種是基於用戶擴展實現的自定義採樣;在自定義採樣設計中,我們將 SofaTracerSpan 實例作爲採樣計算的條件,用戶可以基於此實現豐富的採樣規則。關於採樣機制,期待大家一起編寫,領取方式見文末。

  • SOFATracer 鏈路透傳機制

關於透傳機制,我們不僅需要考慮線程內傳遞,還需要考慮跨線程以及異步線程場景,對於分佈式鏈路來說,最核心還有如何實現跨進程的數據透傳。關於 SOFATracer 鏈路透傳 以及 OpenTracing 新規範中對線程傳遞的支持,期待大家一起編寫,領取方式見文末。

2.2 SOFATracer RoadMap

首先介紹下目前 SOFATracer 的現狀和一些正在做的事情。

在這裏插入圖片描述

SOFATracer 版本說明:

  • 3.x 版本支持 webflux 等,基於分支發佈。
  • 2.x 版本基於master 發佈,目前版本是 2.3.0 。

點擊閱讀更多,查看更多詳情

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章