題干與適用場景
一個多租戶 API 的延遲直方圖在尖峰時段出現 p99 回歸。團隊不能把 user_id、完整 URL 或請求參數加入指標標籤,否則時間序列數量和成本會失控;但只看聚合桶又無法定位某一次慢請求。請設計 metrics exemplar,把少量 Trace 脈絡附著到指標樣本,讓排障人員從圖表跳到 Trace 後繼續追查日誌和依賴。
題目考察候選人能否區分指標的聚合語義與 exemplar 的外部引用。OpenTelemetry 將 exemplar 定義為與一次指標事件關聯的記錄值,可帶 traceid、spanid、觀測時間和過濾後屬性;OpenMetrics 也要求 exemplar 有值、標籤和時間戳。方案必須保持主指標低基數,不能把 exemplar 當成隱藏標籤系統。
面試官考察點
- 是否知道 exemplar 不改變直方圖的 bucket、count、sum,引用的是聚合之外的觀測。
- 是否能設計 Trace-based 或機率取樣,並解釋取樣率、尾延遲命中率與成本取捨。
- 是否使用
traceid、spanid等穩定引用,避免把完整請求、權杖或個人資訊寫入指標。 - 是否處理時間戳、亂序、後端丟棄、保留期和跨租戶權限,而不是只畫一條跳轉連結。
- 是否能用低基數指標定位時間視窗,再用 exemplar 驗證代表性並追到日誌、依賴和版本。
回答前需要釐清的問題
- 指標後端、Trace 後端和視覺化工具分別是什麼,是否支援 exemplar 查詢和深連結?
- 需要覆蓋哪類指標:Histogram、Counter 還是 Gauge?p99 是服務端測量還是閘道測量?
- 取樣目標是所有錯誤、尾延遲,還是按租戶和版本分層?跨地域是否有統一取樣策略?
- Trace 的保留期、存取控制、脫敏規則和跨租戶隔離如何約束引用?
- 允許多少記憶體、網路和儲存開銷,exemplar 丟失時主指標是否仍必須可用?
30 秒回答框架
「我保留低基數的延遲直方圖,把少量命中取樣的 traceid、spanid、值和觀測時間作為 exemplar。取樣優先覆蓋錯誤和尾延遲,不把使用者識別放進指標標籤;指標後端只存短期引用,點擊後由權限檢查跳到 Trace。我要驗證桶統計未被改變、時間視窗能查到 exemplar、丟棄不會影響主指標,並按命中率、跳轉成功率、額外記憶體和敏感欄位洩漏做門禁。」
分步驟深入解答
第一步:定義指標與 exemplar 的邊界
延遲直方圖的標籤只保留 service、routetemplate、region、statusclass 等有限集合。每個樣本的值仍計入 bucketcounts、count 和 sum;exemplar 只保存一條可追溯的觀測引用,不能用 traceid 擴大時間序列維度。
第二步:設計取樣與尾延遲命中
在請求脈絡中先決定是否取樣 Trace,再把已取樣且符合錯誤、超過延遲門檻或分層預算的觀測附到對應 Histogram 樣本。可設定每服務和每指標的固定容量,採用 reservoir 或環形緩衝區;取樣率變更要記錄版本,避免用命中數量直接推斷流量比例。
第三步:編碼引用和時間語義
exemplar 至少包含數值、標籤集合和觀測時間;引用 Trace 時優先使用 traceid 與 spanid。時間應接近觀測發生時刻,並與指標樣本的時間視窗對齊。接收端可能截斷標籤或丟棄 exemplar,因此查詢鏈路要允許「有指標、無 exemplar」。
latency_seconds_bucket{route="/checkout",le="1"} 982
# {trace_id="4f8...",span_id="91a...",build="2026.07.31"} 1.42 1753938000000第四步:控制隱私、基數與成本
禁止把 URL 原文、請求體、電子郵件、授權權杖或使用者 ID 寫入 exemplar。build、區域等可選屬性必須經過白名單和長度限制;OpenTelemetry 還提醒,被 View 從指標流過濾的屬性仍可能出現在 exemplar 的 filtered attributes 中,因此要單獨配置脫敏。估算每秒樣本數、單條位元組、記憶體環形緩衝、遠端寫入和 Trace 查詢成本,超預算時先降低 exemplar 取樣而不是污染指標標籤。
第五步:實作跨後端跳轉
儀表板按 PromQL 或等價查詢先取時間範圍內的 exemplar,再用 trace_id 拼接 Trace 後端的受控連結。連結服務應檢查租戶、地域和權限,並對不存在、過期或跨環境的 Trace 回傳可解釋狀態。日誌和 Span 使用同一 Trace Context,但不要求三種訊號共用儲存。
第六步:驗證退化與發布門禁
用固定流量回放比較啟用前後的 bucket、count、sum 和 p99,證明 exemplar 不改變聚合結果;再注入慢請求和錯誤請求,檢查命中率、時間戳、Trace 跳轉和跨租戶隔離。故意讓 exemplar 後端延遲、截斷或不可用,確認指標仍可查詢。發布門禁至少包含敏感欄位掃描、記憶體上限、遠端寫入失敗率、跳轉成功率和按服務/版本的取樣公平性。
高品質示範回答
「我先把指標標籤限制為路由模板、狀態類別和區域,直方圖繼續負責 p99 聚合。請求進入時沿用 Trace Context;當請求被 Trace 取樣且命中錯誤或尾延遲策略時,向對應 Histogram 樣本附加 traceid、spanid、值和時間戳。exemplar 使用白名單屬性,不攜帶使用者識別或請求體,View 過濾和匯出前再做一次脫敏。」
「Prometheus/OpenMetrics 查詢只取指定時間視窗的 exemplar,儀表板經權限檢查後跳到 Trace;Trace 不存在時保留指標結果並提示引用已過期。壓測比較 bucket/count/sum/p99,故障演練涵蓋後端丟棄、亂序、跨租戶存取和預算耗盡。我們用命中率、排障到首個 Trace 的時間、額外記憶體、寫入成本和敏感欄位掃描結果決定取樣預算,而不是把高基數標籤塞進指標。」
常見錯誤
- 把
trace_id放進指標標籤 → 時間序列爆炸 → 把它放在 exemplar 引用中。 - 只按固定機率取樣 → p99 或錯誤樣本可能長期缺失 → 疊加尾延遲、錯誤和分層預算。
- 忽略 exemplar 時間戳 → 圖表時間視窗查不到對應 Trace → 記錄觀測時間並校驗視窗。
- 把過濾後的敏感屬性當作安全 → 屬性仍可能隨 exemplar 匯出 → 單獨白名單、脫敏和權限檢查。
- 後端丟 exemplar 就報警為指標故障 → 聚合與引用耦合 → 允許指標可用、exemplar 缺失並監控兩者。
- 無限保存引用 → 記憶體和成本不可控 → 固定容量、保留期和取樣預算。
追問及應對
追問一:exemplar 會改變 p99 嗎?
不會。exemplar 的值對應的觀測已經參與 Histogram 的 bucket、count 和 sum;它額外提供引用和脈絡,不應建立新的指標序列或重複計數。
追問二:為什麼不把完整 URL 作為 exemplar 屬性?
完整 URL 可能包含使用者資訊、權杖和無限基數。優先使用路由模板、版本等白名單欄位;需要定位參數時在受控 Trace 或日誌中查看,並按租戶權限脫敏。
追問三:exemplar 全部丟失時系統如何運作?
指標查詢和告警繼續依賴聚合序列。排障人員只會失去從指標到 Trace 的快捷入口,因此應監控 exemplar 接收率和跳轉成功率,不能讓引用鏈路阻塞指標寫入。
追問四:如何證明取樣沒有偏向某個租戶?
按租戶、區域、版本和結果類別統計請求量、取樣量與命中量,設定最小保障和最大預算;比較錯誤與尾延遲命中率,發現偏差後調整分層取樣,而不是提高全域比例。