當系統演化為由數十、甚至數百個服務組成的分散式架構時,僅靠翻閱各服務的 Log 來釐清一筆 Request 的全貌,會耗費大量心力且效率低落。分散式追蹤(Distributed Tracing)正是為了解決這個痛點而生,本章整理它的演變脈絡、核心概念,以及以 OpenTelemetry (OTel) 為主軸的整體資料處理流程。
分散式追蹤的演變#
分散式追蹤的發展可以從幾個指標性的專案來理解:
- Google Dapper:2010 年 Google 公開內部使用的 Tracing 系統,提出了 Trace ID、Span、Sampling 等被後續系統廣泛沿用的概念,可視為這個領域的開山之作。
- Twitter Zipkin:2012 年 Twitter 將內部 Tracing 系統開源,是第一個對外的 Tracing System,提供完整的 SDK、收集、儲存與查詢能力。
- Uber Jaeger:2015 年 Uber 也將自家 Tracing 系統開源,同樣涵蓋 SDK、收集、儲存與查詢的完整流程。
通用 API 的整併#
為了讓各家工具不再各自為政,業界陸續推出多個跨工具的 API 與 SDK 規範:
- OpenTracing:2015 年由 Lightstep 與 Jaeger 作者等人共同發起,目標是建立通用 Tracing API,並於 2016 年加入 CNCF。
- OpenCensus:2017 年由 Google 提出,理念與 OpenTracing 類似。
- OpenTelemetry (OTel):2019 年將 OpenCensus 與 OpenTracing 合併,成為 CNCF 專案,除了提供統一 API 與多語言 SDK,覆蓋範圍也從 Trace 擴展到 Metrics 與 Log,三者統稱為 Telemetry Data。
經過多年整併,OpenTelemetry 已是分散式追蹤領域的事實標準,同時也讓 Trace、Metric、Log 三類訊號能在同一套 API 與資料模型下整合。
Trace 與 Span 的基本結構#
Trace 由多個 Span 組成,整段呼叫鏈以一個 Trace ID 串接,每個 Span 擁有自己的 Span ID 並透過 Parent Span 來表示父子關係,記錄該段操作的開始時間、結束時間、耗時、屬性與事件等資訊。Span 在跨服務傳遞時遵循 W3C Trace Context 規範,透過 Context Propagation 把 Trace ID 與相關欄位放進 HTTP Header 等載體中。
Trace 資料的處理流程#
以 OpenTelemetry 為主軸來看,整體資料流可拆成以下幾個階段:
- 生成:開發者透過 SDK 進行自動插樁(Auto Instrumentation)或手動插樁(Manual Instrumentation),在 HTTP 請求、資料庫查詢等關鍵階段建立 Span。
- 收集:SDK 依照 OTLP(OpenTelemetry Protocol)規範,透過 gRPC 或 HTTP 將資料送往 Tracing Backend,gRPC 因為基於 HTTP/2 通常較為高效。
- 儲存:依後端不同會落地到不同儲存層,例如 Zipkin 支援 Cassandra、Elasticsearch、MySQL;Jaeger 主要採用 Cassandra 與 Elasticsearch;Tempo 則使用 Object Storage(如 Amazon S3、Google Cloud Storage)。
- 使用:透過各家專屬 UI 或 Grafana 來查詢與分析 Trace 資訊。
中間若有額外加工需求,資料也可能先經過 OpenTelemetry Collector、Fluent Bit 等處理器再轉發。
常見 Tracing Backend 與 UI#
常見的後端與檢視介面可整理如下:
- Zipkin:搭配 Zipkin UI 使用。
- Jaeger:搭配 Jaeger UI 使用。
- Tempo:以 Grafana 作為主要 UI。
- Grafana:可同時串接 Zipkin、Jaeger、Tempo 等多種資料源,方便跨後端比較。
小結#
Tracing 在十多年的演進中已逐步成熟,OpenTelemetry 的出現補齊了 API 與生態系的最後一塊拼圖。今日只要選定支援 OTel 的 SDK,無論主後端是 Tempo、Jaeger 還是商業 SaaS,都能透過 OTLP 進行資料交換,未來搬遷或更換廠商的成本也大幅降低。
原文出處#
- 原書/iThome:https://ithelp.ithome.com.tw/articles/10333505