iT邦幫忙

2025 iThome 鐵人賽

DAY 12
0
DevOps

被稱作Server Restart Engineer的我,也想了解如何實踐可觀測性工程系列 第 12

Day 12 - OpenTelemetry Signal: Baggage 跨服務的上下文傳遞機制

  • 分享至 

  • xImage
  •  

在昨天的 Traces 介紹中,我們了解到 SpanContext 提供了追蹤關聯性,讓分散式系統中的操作能夠正確地關聯到同一個 trace。然而,在實際的業務場景中,我們往往希望請求能攜帶一些額外的上下文資訊,例如用戶ID、所在地區、實驗標籤等。雖然 SpanContext 提供了基本的追蹤關聯性,但對於這類業務上下文的傳遞,OpenTelemetry 提供了另一個重要的機制:Baggage

Baggage:業務上下文的載體

Baggage 是一個 key-value 形式的上下文資訊儲存機制,專門用於在分散式系統的服務間傳遞業務相關的 metadata。與 SpanContext 不同,Baggage 不是用來追蹤 span 之間的關係,而是用來攜帶對業務邏輯有意義的額外資訊。

讓我們來盤點一下這兩者的差異:

SpanContext(追蹤資訊):

  • 包含 Trace ID、Span ID、Trace Flags
  • 專門用於追蹤關聯性
  • 不可變,生成後無法修改
  • 由 OpenTelemetry 自動管理

Baggage(業務資訊):

  • 彈性的 key-value 結構
  • 用於傳遞業務上下文
  • 可變,服務可以新增、修改項目
  • 需要應用程式主動操作

Baggage 的運作機制

還記得昨天我們介紹到 W3C 協議,Baggage 透過與 W3C Trace Context 類似的標準化方式進行跨服務傳播。當 HTTP 請求在不同服務間傳遞時,Baggage 資訊會透過專門的 HTTP header 來傳遞:

baggage header

  • 格式:key1=value1,key2=value2,key3=value3
  • 例如:user_id=12345,region=asia-pacific,experiment_group=feature-a
GET /api/orders HTTP/1.1
Host: order-service.example.com
traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
baggage: user_id=12345,region=asia-pacific,experiment_group=feature-a

安全考量

由於 Baggage 會在網路中傳輸,使用時需要注意以下幾點:

  • 資料暴露:Baggage 可能暴露在網路流量中,不應包含敏感資訊
  • 資料完整性:沒有內建的完整性檢查機制
  • 大小限制:過多資料會增加網路負載

實作範例

以下是使用 Python SDK 操作 Baggage 的完整範例:

from opentelemetry import baggage, trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor, ConsoleSpanExporter

# 初始化 Tracer
trace.set_tracer_provider(TracerProvider())
tracer = trace.get_tracer(__name__)
span_processor = SimpleSpanProcessor(ConsoleSpanExporter())
trace.get_tracer_provider().add_span_processor(span_processor)

# 在服務入口設定 Baggage
with tracer.start_as_current_span("user-request") as span:
    # 設定業務上下文到 Baggage
    ctx = baggage.set_baggage("user_id", "12345")
    ctx = baggage.set_baggage("region", "asia-pacific", context=ctx)
    ctx = baggage.set_baggage("experiment_group", "feature-a", context=ctx)

    # 呼叫下游服務
    with tracer.start_as_current_span("call-downstream-service", context=ctx):
        # 在任何地方都可以取得 Baggage 資訊
        user_id = baggage.get_baggage("user_id")
        region = baggage.get_baggage("region")
        experiment = baggage.get_baggage("experiment_group")

        print(f"處理用戶 {user_id} 在 {region} 的請求,實驗組別:{experiment}")

        # 將 Baggage 資訊加入到 span attributes
        span.set_attribute("user.id", user_id)
        span.set_attribute("user.region", region)
        span.set_attribute("experiment.group", experiment)

與 Span attributes 的整合

Baggage 本身不會自動成為 span 的 attributes,需要明確地將 Baggage 資訊複製到 span 中:

def add_baggage_to_span(span):
    """將重要的 Baggage 資訊加入到當前 span"""
    user_id = baggage.get_baggage("user_id")
    region = baggage.get_baggage("region")

    if user_id:
        span.set_attribute("business.user_id", user_id)
    if region:
        span.set_attribute("business.region", region)

應用場景與最佳實務

Baggage 本身雖然可以讓我們很好地攜帶上下文,但是,也不是任何資訊都適合放在 baggage 中傳輸,除了安全性的考量以外,過於龐大的 baggage 資訊可能也會影響到傳輸上的效能。

適用場景

  1. 用戶標識傳遞:將用戶ID、會話資訊傳遞到各個服務
  2. 功能開關:傳遞功能開關狀態,讓下游服務知道要啟用哪些功能
  3. A/B 測試:傳遞實驗分組資訊,確保整個請求鏈使用一致的實驗版本
  4. 地區資訊:傳遞用戶所在地區,用於合規性或本地化處理

不適用場景

  1. 敏感資料:密碼、信用卡號等敏感資訊不應放入 Baggage
  2. 大量資料:Baggage 會增加網路負載,應保持精簡
  3. 頻繁變動資料:不適合放入經常變化的資料

效能考量

# 好的做法:精簡且有意義的資訊
ctx = baggage.set_baggage("user_tier", "premium")
ctx = baggage.set_baggage("region", "us-west", context=ctx)

# 避免的做法:過多或敏感的資訊
ctx = baggage.set_baggage("user_password", "secret123")  # 敏感資訊
ctx = baggage.set_baggage("large_data", "..." * 1000)    # 資料過大

結語

Baggage 為 OpenTelemetry 補足了業務上下文傳遞的能力,讓我們不僅能夠追蹤技術層面的請求流程,更能在整個分散式系統中保持業務層面的上下文資訊。透過適當的使用,Baggage 能夠讓 traces、logs 和 metrics 包含更豐富的業務語義,提升可觀測性的價值。

參考資料

OpenTelemetry Docs - Baggage

W3C Baggage

OpenTelemetry Python SDK - Baggage API


上一篇
Day 11 - OpenTelemetry Signal: Traces 分散式系統的因果關係哲學
下一篇
Day 13 - 資料要存在哪裡?Data Lake到Data Lakehouse的技術演進
系列文
被稱作Server Restart Engineer的我,也想了解如何實踐可觀測性工程14
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言