Jaeger 是由 Uber 於 2015 年 8 月開始開發的分散式追蹤(Distributed Tracing)工具,2017 年成為 CNCF 孵化專案,並在 2019 年 10 月晉升為畢業專案。它具備完整的資料收集、儲存與查詢介面,支援 Cassandra 與 Elasticsearch 作為主要儲存方式,並同時支援 Jaeger 自家、OpenTelemetry、Zipkin 等多種 API。Jaeger 過去維護自家 SDK,但自 2022 年 1 月最後一版後即停止維護,官方建議改用 OpenTelemetry SDK。

Jaeger 在德文中是「獵人」之意,發音為 ˈyā-gər,呼應分散式追蹤的「追蹤、偵查、解決問題」的意象。

架構#

Jaeger 官方的 Getting Started 提供了 all-in-one 版本,可以用單一 Binary 或 Container 把所有元件跑起來、Trace 暫存在記憶體中,但僅適合初步體驗。生產環境通常會以分散式方式部署,主要包含三個部分:

  • Jaeger Collector:接收 SDK 送來的 Trace Data,處理後寫入 Storage。
  • Storage:實際存放 Trace Data,支援 Cassandra、Elasticsearch、Kafka 與 Memory Storage 等;其中 Kafka 主要用於高流量緩衝,仍需搭配 Cassandra、Elasticsearch 等真正提供儲存能力的服務。
  • Jaeger Query:提供 UI 查詢與檢視 Trace Data。

較舊版本還會看到 Jaeger Agent,用於本地加工與轉發 Trace Data,自 1.43 後已不再維護,相同需求建議改用 OpenTelemetry Collector。

API 與 Port 對應#

Jaeger 因為發展時間長,支援的 API 相當多種,選錯 Protocol 與 Port 容易陷入除錯地獄。常見的四組 Collector Port 對應如下:

  • 14250(gRPC):接收 Jaeger model.proto 格式的 Trace Data。
  • 14268(HTTP):接收 Jaeger jaeger.thrift 格式的 Trace Data,需加上 /api/traces 路徑。
  • 4317(gRPC):接收 OTLP 格式的 Trace Data,Collector 需以 --collector.otlp.enabled=true 啟用。
  • 4318(HTTP):接收 OTLP 格式的 Trace Data,啟用方式同上。

從 v1.35 起,Jaeger Collector 正式支援 OpenTelemetry Protocol(OTLP),SDK 可直接送資料給 Jaeger,不再需要中間的格式轉換。也因為 OTLP 支援逐漸完整,OpenTelemetry SDK 中針對 Jaeger 的多數舊 API 已於 2023 年 7 月後逐步停止維護,未來新建置時應優先採用 OTLP。

Sampling#

每筆 Request 都會帶來大量 Trace 資料,全量保留的儲存成本通常難以承受,因此需要透過 Sampling 機制只保留部分 Trace。Jaeger 提供兩種採樣策略:

  • File-based Sampling:在設定檔中以規則決定是否保留 Trace,常見組合是基於機率的 probabilistic(如某服務只取 80% 的 Trace)與基於每秒頻率的 ratelimiting(如每秒只取 2 筆)。
  • Adaptive Sampling:依即時流量動態調整採樣比率,需要額外儲存統計資料,可選擇 Memory 或 Cassandra。

實作上由 Jaeger Collector 提供採樣策略,並以 sampling.proto 格式供 SDK 輪詢取得;SDK 依拉到的策略決定是否送出 Trace Data。OpenTelemetry SDK 端可設定 JaegerRemoteSampler,指定 Collector 的採樣 endpoint,例如:

  • http://<jaeger-collector>:14268/api/sampling
  • <jaeger-collector>:14250

也可透過環境變數 OTEL_TRACES_SAMPLEROTEL_TRACES_SAMPLER_ARG 進行設定。

Jaeger 採用的是 Head-Based Sampling 的設計:是否保留 Trace 在請求一開始就決定,由 SDK 與 Collector 協作;對應的另一種策略是 Tail-Based Sampling,會等 Trace 完整後再決定,常見於 OpenTelemetry Collector 等中介層。

範例情境#

官方 Lab 中以四種方式同時送 Trace Data,方便對照不同 API:

  • A:以 gRPC 將 OTLP Trace Data 送往 Jaeger Collector 的 4317
  • B:以 HTTP 將 OTLP Trace Data 送往 Jaeger Collector 的 4318
  • C:以 gRPC 將 jaeger.thrift Trace Data 送往 14268
  • D:以 HTTP 將 model.proto Trace Data 送往 14250

Collector 會把 Trace Data 寫入 DB,Jaeger Query 則從 DB 讀取後提供 UI 檢視,Grafana 也可用 Jaeger 作為 Data Source 進行交叉查詢。

小結#

Jaeger 是分散式追蹤領域最早一批進入生產實戰的工具之一,今日仍然憑藉成熟的架構與對 OpenTelemetry 的擁抱在微服務世界中占有一席之地。對於已經部署 Cassandra 或 Elasticsearch 的團隊,Jaeger 是一個能直接接 OTLP、又有完整 UI 的成熟選擇。

原文出處#

  • 原書/iThome:https://ithelp.ithome.com.tw/articles/10335489