單體時代靠 Stack Trace 一路追到根源;一旦調用鏈跨越進程邊界,Stack Trace 就斷了。分散式追蹤把散落在各服務 log 裡的「頁碼」接回去——用同一個 Trace ID 串起一個請求的完整旅程,讓你看得出哪一段慢、哪一段錯。
🧠 Intuition
TIP
只要三個概念:Trace 是一個請求的完整旅程(一個唯一的 Trace ID);Span 是旅程中的一段操作(帶名稱、起訖時間、狀態,與它的 parent span);Span Context 是跨服務傳播的上下文(至少含 Trace ID 與 Span ID)。多個 Span 以 parent-child 形成樹,就是 UI 上那張瀑布圖。
- 接鏈的機制是 Context Propagation:把 Span Context 從一個服務帶到下一個——HTTP 放進
traceparentheader(W3C Trace Context 標準)、gRPC 放進 metadata、訊息佇列放進 message header。下游取出後建 child span、繼承同一個 Trace ID。 - 格式必須一致:A 服務用 W3C、B 服務用 B3,追蹤鏈就在交界斷掉——這正是 OpenTelemetry 統一標準的價值。
- Span 不限於服務間呼叫,服務內的重要操作(DB 查詢、快取存取)也能是獨立 span;粒度由你定,但越細開銷越大。
- 資料流程與其他遙測一致:生成(instrumentation,可 zero-code / library / manual)→ 收集(通常先過 OTel Collector)→ 儲存(Tempo 走物件儲存低成本、Jaeger 支援 Elasticsearch/Cassandra)→ 使用(UI 看鏈路、分析瓶頸、產生 service graph)。
⚖️ Tradeoffs
標準之爭 — 從 Dapper 到 OpenTelemetry
- 2010 Google Dapper 論文奠定 Trace / Span / Annotation 的理論基礎,幾乎所有後來的系統都受其啟發。
- 2012 Twitter 開源 Zipkin(B3 propagation 格式)是第一個廣泛使用的開源追蹤系統;2016 Uber 開源 Jaeger,效能與擴展更好,後成 CNCF 畢業專案。
- 2016 OpenTracing 與 2017 OpenCensus 各自想統一 API,卻互相競爭;2019 兩者合併成 OpenTelemetry,一套涵蓋 Traces / Metrics / Logs。
- 今天開新專案直接選 OpenTelemetry——已是業界事實標準,不必再糾結 OpenTracing 與 OpenCensus 的差異。
Head-based vs Tail-based Sampling — 為何不追蹤每個請求
- 高流量下全追不現實:每秒一萬請求、每請求 20 個 span,就是每秒 20 萬 span,儲存與傳輸成本驚人,所以要取樣。
- Head-based:請求一進來就決定追不追(如 10% 機率)。簡單、開銷低;盲點是決策發生在還不知道結果之時,可能漏掉罕見但重要的錯誤請求。
- Tail-based:先收集所有 span,請求結束後再依結果(錯誤、高延遲)決定保留。判斷更聰明,但需暫存大量資料、實作複雜。
- 準則:最在意錯誤追蹤 → 選 tail-based,但要有承擔其複雜度的準備。
🔑 Takeaways
- Trace / Span / Span Context 三概念 + Context Propagation(
traceparent、gRPC metadata、訊息 header)把跨服務請求串成一條可讀的瀑布圖。 - 傳播格式必須一致,OpenTelemetry(2019 由 OpenTracing + OpenCensus 合併)是統一標準與新專案的預設選擇。
- 全追不現實 → 取樣;head-based 便宜但會漏錯誤請求,tail-based 更聰明但更複雜。服務數超過約 5 個、或需精確定位延遲落在哪一段時,追蹤的價值才真正浮現。
No notes yet — jot your takeaways or Q&A here.