題目與範圍
上下文傳播能讓跨服務請求保持可理解,但每個下游服務都可能接收並記錄這些值。OpenTelemetry 將 Baggage 定義為與追蹤上下文相鄰的鍵值資料,並明確提醒傳播帶來的安全影響。核心能力是分散式邊界設計,因此分類為 system-design。
面試官考察點
優秀回答會把追蹤上下文與應用元資料分開,為欄位定義允許清單和負責人,並阻止敏感值跨越不可信邊界。還應涵蓋請求標頭大小、正規編碼、採樣、重試、非同步訊息,以及上下文損壞或缺失時的處理。指標要證明傳播有價值,避免把它變成失控的資料通道。
先釐清的問題
- 哪些協議承載上下文:HTTP、gRPC、佇列還是排程工作?
- 哪些欄位用於診斷,哪些會改變行為,各欄位由誰負責?
- 租戶、區域和第三方服務之間有哪些信任邊界?
- 值是否允許進入日誌、指標標籤,還是只能進入追蹤?
- 請求標頭大小、延遲和可用性預算是多少?
- 上下文損壞時應拒絕、剝離,還是建立新根?
30 秒答題框架
「定義一個小型、帶版本的封裝,將追蹤上下文與批准的業務欄位分離。每個邊界由策略函式庫驗證名稱、大小、編碼、租戶範圍和目標信任級別,剝離或拒絕不允許的值,絕不轉發金鑰。同步和非同步邊界都要傳播,限制請求標頭,並定義缺失上下文行為。指標記錄擷取失敗、截斷、覆蓋率、跨租戶違規和追蹤連接率。」
分步作答
步驟 1:定義上下文契約
建立欄位註冊表,記錄負責人、類型、最大長度、敏感級別、保留期和允許目的地。追蹤識別留在追蹤協議中,獨立載體只放批准的業務元資料。封裝帶版本,消費者可拒絕未知的關鍵欄位。
步驟 2:執行邊界策略
使用共用中介軟體或 sidecar 解析載體,驗證編碼和大小,檢查租戶與信任區,再產生清洗後的載體。不能把任意入站請求標頭複製到出站請求。第三方和跨租戶呼叫預設視為新的信任根,除非策略明確允許。
步驟 3:處理傳輸與重試
為 HTTP、gRPC metadata 和訊息屬性定義對應載體。非同步工作只持久化關聯所需欄位,不能把金鑰序列化進佇列。重試保留原追蹤關係,同時重新驗證業務欄位,避免重複或過期決策被盲目信任。
步驟 4:設計失敗行為
依端點風險決定剝離或拒絕損壞、超大的上下文;安全時請求本身繼續處理並建立新的本地追蹤根。暴露帶原因碼的計數器,不暴露原始值。讓策略版本和執行結果可供維運查看。
步驟 5:營運並證明價值
追蹤追蹤連接率、擷取和注入失敗、增加位元組數、截斷、策略拒絕、跨邊界違規和佇列序列化錯誤。避免把高基數原值放進指標標籤。為每個協議建立契約測試,在強制拒絕前先灰度策略。
參考答案
「把傳播上下文視為不可信資料通道。版本化註冊表定義可傳播的診斷與業務欄位、敏感級別和大小。中介軟體逐跳驗證和清洗,第三方及跨租戶呼叫採用更嚴格規則;金鑰不能進入載體或佇列。追蹤上下文與業務 Baggage 分開。支援 HTTP、gRPC 和非同步屬性,定義剝離與拒絕,監控連接率、策略失敗、位元組數和違規。灰度策略與原因碼指標支援逐步收緊而不損失可觀測性。」
常見錯誤
- 轉發所有入站請求標頭 → 不可信資料跨越邊界 → 使用允許清單和清洗器。
- 把令牌或 PII 放入 Baggage → 下游日誌和服務可能暴露 → 排除敏感資料。
- 用 Baggage 做指標標籤 → 基數和成本失控 → 記錄有界原因碼與維度。
- 忽略佇列和重試 → 非同步工作丟失或信任過期上下文 → 定義傳輸契約並重新驗證。
- 所有損壞請求都拒絕 → 可觀測性與可用性下降 → 按端點風險選擇剝離或拒絕。
- 沒有大小預算 → 請求標頭導致代理失敗 → 限制欄位和總載體大小。
追問
追問 1:租戶 ID 應該傳播嗎?
只有當目的地獲准處理該租戶,且值已與驗證身分核對時才傳播。租戶 ID 本身不能成為授權依據。
追問 2:追蹤上下文與 Baggage 有何區別?
追蹤上下文連接 span 和傳播狀態;Baggage 攜帶應用自訂鍵值資料,因此需要更嚴格的敏感性、所有權和目的地策略。
追問 3:如何阻止請求標頭增長?
設定欄位和總量預算,超限時按原因碼拒絕或截斷;若必須攜帶更大內容,改用有界的伺服器狀態引用。
追問 4:到達不可信邊界怎麼辦?
剝離非批准欄位,只繼續傳播策略允許的追蹤資訊,並記錄策略決定,不記錄敏感值。