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

SOFA Scalable Open Financial Architecture 是螞蟻金服自主研發的金融級分佈式中間件,包含了構建金融級雲原生架構所需的各個組件,是在金融場景裏錘鍊出來的最佳實踐。
SOFATracer 是一個用於分佈式系統調用跟蹤的組件,經過統一的 TraceId 將調用鏈路中的各類網絡調用狀況以日誌的方式記錄下來,以達到透視化網絡調用的目的,這些鏈路數據可用於故障的快速發現,服務治理等。 SOFAT racer https://github.com/alipay/sofa-tracer

本文爲《剖析 | SOFATracer 框架》第一篇。《剖析 | SOFASOFATracer 框架》系列由 SOFA 團隊和源碼愛好者們出品, 項目代號:<SOFA:TracerLab/>文章尾部有參與方式,歡迎一樣對源碼熱情的你加入html


0、前言

在單體應用時代,咱們不須要花費時間去關心調用鏈路這個東西。可是鏈路跟蹤不只僅是在分佈式場景下才會有,即便是單體應用,一樣也會存在調用鏈路。例如,咱們把應用中的每一個服務接口做爲一個鏈路節點,那麼從請求進來到返回響應,把這個過程當中多歷經的全部的方法接口串聯起來,就能組成一條完整的鏈路,以下圖所示:git

image.png | center | 747x201
對於單體應用而言,若是訪問一個資源沒有成功,那麼咱們能夠很快的鎖定是哪一臺機器,而後經過查詢這臺機器上的日誌就能定位問題。
可是在微服務體系架構下,這種方式會顯得很是無力。對於一個稍具規模的應用來講,一次請求可能會跨越至關多的服務節點,在這種狀況下,若是一個請求沒有獲得成功的響應,就不能肯定究竟是哪一個節點出了問題。
image.png | center | 747x157
所以在面對這種複雜的大規模分佈式集羣來實現的服務體系來講,就須要一些能夠幫助理解各個應用的線上調用行爲、並能夠分析遠程調用的組件。
基於上述背景,螞蟻金服開源了基於 OpenTracing 規範 opentracing.io/documentati… )實現的 SOFATracer 分佈式鏈路跟蹤組件,爲實施大規模服務化體系架構場景下提供了鏈路跟蹤的解決方案。
在介紹 SOFATracer 以前,先來了解一下 Opentracing 規範。

一、Opentracing 簡介

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

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

1.一、數據模型

Opentracing 規範中,一條 trace 鏈路是由多個與之關聯的 span 組成,一條鏈路總體能夠看作是一張有向無環圖,各個 span 之間的邊緣關係被稱之爲「 References 」。下面是官方提供的示例:
image.png | center | 742x290
若是已時間軸維度來看的話,也能夠表現爲下面的形式(官方示例):
image.png | center | 763x162
root span : 當前鏈路中的第一個 span
ChildOfFollowFrom 是目前被定義的兩種 References 類型 ChildOf : 父級 span某種程度上取決於子span (子span的結果可能會對父span產生影響)
FollowFrom : 父 Span不以任何方式依賴子 Span
可是爲了簡化 span 之間的這種依賴關係,在具體實現時一般會將具備嵌套關係的做爲 ChildOf ,平行執行的做爲 FollowFrom ,好比:
a、ChildOf 示例
methodA 中調用了 method B :


產生的 span 在時間維度上展示的視角以下:
image.png | left | 622x84
這種關係通常會 表示爲 SpanBChildOfSpanA
b、FollowFrom 示例
method 方法中, methodA 執行以後 methodB 執行 :


產生的 span 在時間維度上展示的視角以下:
image.png | left | 622x64
這種關係通常會 表示爲 SpanBFollowFromSpanA

1.二、API

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

1.三、SOFATracer 標準實現

下圖爲 SOFATracer 中對於這三個核心接口實現的類圖結構:
image.png | center | 566x310

因爲篇幅緣由,下面的介紹過程當中一些點不會展開說明,有興趣的同窗能夠自行官網查看完整的 OpenTracing-api 規範opentracing.io/specificati…)。web

a、Tracer & SofaTracer
Tracer 是一個簡單、廣義的接口,它的做用就是構建 span 和傳輸 span 。核心接口列表以下:
接口 描述
SpanBuilder buildSpan(String operationName) 根據指定的operationName構建一個新的span
void inject(SpanContext spanContext, Formatformat, C carrier); 將 spanContext 以 format 的格式注入到 carrier 中
SpanContext extract(Format format, C carrier); 以 format 的格式從carrier中解析出 SpanContext
SofaTracer 實現了 Tracer 接口,並擴展了採樣、數據上報等能力。
_b、Span & SofaTracerSpan _
Span 是一個跨度單元,在實際的應用過程當中, Span 就是一個完整的數據包,其包含的就是當前節點所須要上報的數據。核心接口列表以下:
接口 描述
SpanContext context() 從 span 中獲取 SpanContext
void finish()/void finish(long finishMicros) 結束一個 span
void close() 關閉 span
Span setTag(String key, value) 設置 tags
Span log(long timestampMicroseconds, String event) 設置 log 事件
Span setOperationName(String operationName) 設置span的operationName
Span setBaggageItem(String key, String value) 設置 BaggageItem
String getBaggageItem(String key) 獲取 BaggageItem

關於 tagslog的解釋:若是把從進入公司到離開公司這段時間做爲一個 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 實例成爲不可變的,以免 Spanfinishreference 操做時會有複雜的生命週期問題。」 這裏是能夠理解的,若是 SpanContext 在透傳過程當中發生了變化,好比改了 tracerId,那麼就可能致使鏈路出現斷缺。api

SpanContext 中只有一個接口:
接口 描述
Iterable> baggageItems(); 拿到全部的baggageItems 透傳數據
SofaTracerSpanContext 實現了 SpanContext 接口,擴展了構建 SpanContext 、序列化 baggageItems 以及 SpanContext 等新的能力,除此以外, SpanContext 在跨進行透傳時攜帶的信息進行了規範:
攜帶信息 描述
traceId 全鏈路惟一的標識信息
spanId spanId
parentId 父 spanId
isSampled 採樣標記
sysBaggage 系統透傳數據
bizBaggage 業務透傳數據

二、SOFATracer 擴展

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

2.一、SOFATracer 架構及功能擴展

image.png | left | 747x279
SOFATracer 基於 OpenTracing 規範 opentracing.io/specificati… )實現,而且經過 Disruptor github.com/LMAX-Exchan… )組件實現了日誌的無鎖異步打印能力。
基於 SLF4J 的 MDC 擴展能力
應用在經過面向日誌編程接口 SLF4J 打印應用日誌時,能夠只在對應的日誌實現配置文件的 PatternLayout 中添加相應的參數便可,如添加 [%X{SOFA-TraceId},%X{SOFA-SpanId}] ,那麼應用日誌就能夠在發生鏈路調用時打印出相應的 TraceId SpanId ,而不管應用具體的日誌實現是 Logback Log4j2 或者 Log4j 。關於這部分的實現原理,期待你們一塊兒編寫,領取方式見文末。
SOFATracer 的埋點機制
SOFATracer 目前僅提供了基於自身 API 埋點的方式。 SOFATracer 中全部的插件均須要實現本身的 Tracer 實例,如 Mvc SpringMvcTracer HttpClient HttpClientTracer 等,以下圖所示:
image.png | center | 607x272
SOFATracer 將不一樣的擴展組件分爲 AbstractClientTracer AbstractServerTracer ,再經過 AbstractClientTracer AbstractServerTracer 衍生出具體的組件 Tracer 實現。這種方式的好處在於,全部的插件實現均有 SOFATracer 自己來管控,對於不一樣的組件能夠輕鬆的實現差別化和定製化。
可是爲了可以擁抱社區,咱們在後續的版本中將會提供基於 OpentracingAPI 的埋點擴展實現,從而實現與 opentracing-contrib 的無縫對接。基於 OpentracingAPI 的插件埋點方案以下圖所示:
image.png | center | 663x225
關於 SOFATracer 基於特有 API 埋點的實現以及如何實現對接 OT-api 埋點,期待你們一塊兒編寫,領取方式見文末。
SOFATracer 的數據上報機制
SOFATracer 中並無將不一樣的 Reporter 設計成不一樣的策略,而後根據不一樣的策略來實現具體的上報操做,而是使用了一種相似組合的方式,而且在執行具體上報的流程中經過參數來調控是否執行具體的上報。
image.png | center | 306x514
從流程圖中能夠看到,此過程當中涉及到了三個上報點,首先是上報到 zipkin ,後面是落盤;在日誌記錄方面, SOFATracer 中爲不一樣的組件均提供了獨立的日誌空間,除此以外, SOFATracer 在鏈路數據採集時提供了兩種不一樣的日誌記錄模式:摘要日誌和統計日誌,這對於後續構建一些如故障的快速發現、服務治理等管控端提供了強大的數據支撐。關於數據上報,期待你們一塊兒編寫,領取方式見文末。
SOFATracer 的採樣機制
對於鏈路中的數據,並不是全部的數據都是值得關注的。一方面是能夠節約磁盤空間,另外一方面能夠將某些無關數據直接過濾掉。基於此, SOFATracer 提供了鏈路數據採樣能力。目前咱們提供了兩種策略,一種是基於固定比率的採樣,另外一種是基於用戶擴展實現的自定義採樣;在自定義採樣設計中,咱們將 SofaTracerSpan 實例做爲採樣計算的條件,用戶能夠基於此實現豐富的採樣規則。關於採樣機制,期待你們一塊兒編寫,領取方式見文末。
SOFATracer 鏈路透傳機制
關於透傳機制,咱們不只須要考慮線程內傳遞,還須要考慮跨線程以及異步線程場景,對於分佈式鏈路來講,最核心還有如何實現跨進程的數據透傳。關於 SOFATracer 鏈路透傳 以及 OpenTracing 新規範中對線程傳遞的支持,期待你們一塊兒編寫,領取方式見文末。

2.二、SOFATracer RoadMap

首先介紹下目前 SOFATracer 的現狀和一些正在作的事情。
image.png | left | 747x260
SOFATracer 版本說明:
3.x 版本支持 webflux 等,基於分支發佈。
2.x 版本基於 master 發佈,目前版本是 2.3.0 。
歡迎對相關功能和 feature 有興趣的同窗,一塊兒參與開發~

三、歡迎加入 ,參與 SOFATracer 源碼解析

本文做爲《剖析 | SOFATracer 組件系列》第一篇,主要仍是但願你們對 SOFATracer 組件有一個認識和了解,以後,咱們會逐步詳細介紹每部分的代碼設計和實現,預計會按照以下的目錄進行:架構

  • 分佈式鏈路跟蹤組件 SOFATracer 概述【已完成】
  • SOFATracer 數據上報機制和源碼分析【待領取】
  • SOFATracerAPI組件埋點機制和源碼分析【待領取】
  • SOFATracer鏈路透傳原理與 SLF4J MDC 的擴展能力分析【待領取】
  • SOFATracer 的採樣策略和源碼分析【待領取】
若是有同窗對以上某個主題特別感興趣的,能夠留言討論,咱們會適當根據你們的反饋調整文章的順序,謝謝你們關注 SOFA ,關注 SOFATracer ,咱們會一直與你們一塊兒成長的。
領取方式: 掃碼關注公衆號,後臺回覆想認領的文章名稱,咱們將會主動聯繫你,確認資質後,便可加入 ,It's your show time!

除了源碼解析,也歡迎提交 issue 和 PR: SOFATracerhttps://github.com/alipay/sofa-tracer框架

長按關注,獲取分佈式架構乾貨異步

歡迎你們共同打造 SOFAStack https://github.com/alipay

相關文章
相關標籤/搜索