Metric instrumentation: from Dropwizard to OpenTelemetry
謝朝華 (Paul)/Software Engineer, Taboola
2026-04-23 12:05 - 12:45 @ 張榮發基金會國際會議中心 11F
Taboola 每分鐘管理超過 10 億筆指標,主要由數千個 Java 執行個體產生。雖然 Dropwizard 長期以來一直是我們在 Java 上的 instrumentation 解決方案,但本場演講將說明我們如何轉向 OpenTelemetry,內容包含:
- Dropwizard 在 Taboola 指標架構中的角色
- 轉向 OpenTelemetry 的動機
- 在維持向下相容性時遇到的技術挑戰
- 平順轉換的策略
雖然本場演講聚焦於 Java instrumentation 函式庫,但相關經驗具有普遍性;不需要具備 Java 專業知識。
聽眾收穫:
- 辨識遷移到現代化、開源可觀察性標準 OpenTelemetry 的關鍵動機。
- 學習在遷移指標 instrumentation 時,如何確保向下相容、降低干擾,並掌握實務策略與技術考量。
Taboola 背景
Taboola 是一個在搜尋與社群平台之外,提供大規模內容推薦與廣告效能的平台。
簡報中提到的公司規模包括:
- 11K+ 全球發布商
- 18K+ 全球廣告主
- 2K+ 員工
- 其中約 500 人在研發部門
- 35 個全球辦公室
- 600M+ 每日活躍用戶
- 130M+ 年度研發投資
這樣的規模意味著 Taboola 的可觀察性與指標系統必須支援非常高的資料量與長期演進需求。
指標拓樸
Taboola 的指標規模非常大:
每分鐘 1B+ 指標
在這種規模下,指標檢測函式庫的設計會直接影響:
- 儲存成本
- 查詢效能
- Prometheus 錄製規則的可維護性
- 指標命名一致性
- 儀表板與告警的穩定性
- 指標與追蹤的串接能力
- 系統遷移時的相容性與風險
因此,從舊有指標函式庫遷移到 OpenTelemetry,不只是換一套 API,而是整個可觀察性基礎建設的演進。
指標函式庫與 Dropwizard 歷史
Taboola 原本使用 Dropwizard 指標系統。
Dropwizard 在早期提供了簡單直接的指標檢測能力,但隨著系統規模擴大,以及 Prometheus、OpenTelemetry 等生態成熟,逐漸出現一些限制。
這次遷移的核心動機包括:
- 可聚合直方圖
- 語意化名稱與標籤
- 錄製規則可擴展性
- 範例資料整合
動機:可聚合直方圖
Dropwizard 的摘要指標問題
Dropwizard 會輸出摘要指標。
這類指標的特性是:
- 分位數在用戶端計算。
例如:latency_p99{instance="web-0"}
優點是:
- 單一執行個體的 p99 精確度很好。
但問題是:
- 用戶端計算的分位數不容易跨執行個體聚合。
- 當服務有多個執行個體時,無法直接得到正確的整體 p99 延遲。
整體 p99 延遲的問題
假設有兩個執行個體:
latency_p99{instance="web-0"} = 1
latency_p99{instance="web-1"} = 10
這時如果想知道整體 p99 延遲,不能直接平均:
(1 + 10) / 2
因為每個執行個體處理的請求數量可能不同。
例如:
web-0 處理了 100 個請求
web-1 處理了 1 個請求
此時單純平均會嚴重扭曲實際整體延遲。
加權平均也不是正確解法
可能有人會嘗試用加權平均:
sum(count * p99) / total_count
但 p99 這種分位數本身並不能透過加權平均正確聚合。
正確方向是使用直方圖,讓分位數在查詢時根據 bucket 分布計算,而不是在用戶端預先算好 p99。
動機:語意化名稱與標籤
Dropwizard 的命名限制
Dropwizard 指標通常是以點號分隔的字串。
例如:
requests.count
這種命名方式在傳統系統中容易使用,但轉到 Prometheus 時,會遇到語意化名稱與標籤表達能力不足的問題。
Taboola 的 Prometheus 對應方式
Taboola 原本將 Dropwizard 指標對應成類似以下形式:
SERVICE_counter{_label_0="requests", _label_1="count"}
這代表原本應該是語意化指標名稱或標籤的資訊,被塞進通用標籤中。
問題包括:
- 指標名稱過於通用。
- 標籤命名缺乏語意。
- 查詢不直覺。
- 錄製規則難以針對業務語意設計。
- 儀表板與告警規則可讀性較差。
動機:錄製規則可擴展性
通用名稱造成可擴展性瓶頸
當大量指標都使用通用名稱時,錄製規則會變得難以擴展。
例如原本可能有:
SERVICE_counter
SERVICE_histogram_p99
錄製規則可能寫成:
record: SERVICE_counter_total:rate
expr: sum without (instance) (rate(SERVICE_counter[5m]))
這種做法的問題是:
- 不同語意的計數器被集中到同一個通用指標名稱。
- 查詢與聚合需要依賴
_label_0、_label_1之類的非語意標籤。 - 錄製規則數量與複雜度會隨服務規模增加而惡化。
- PromQL 可讀性與維護性下降。
語意化命名後的改善
原本:
SERVICE_counter{_label_0="getInfo"}
SERVICE_counter{_label_0="getMetadata"}
可以轉換為:
get_info_total{}
get_metadata_total{}
這樣的好處是:
- 指標名稱本身帶有語意。
- 錄製規則可以針對具體指標設計。
- 查詢更直覺。
- 儀表板與告警更容易維護。
- Prometheus 的資料模型更符合原生使用方式。
動機:範例資料整合
範例資料的目的,是讓使用者可以從指標深入追到追蹤資料。
也就是當某個指標顯示延遲上升、錯誤增加或異常尖峰時,可以透過範例資料連結到對應追蹤,進一步查看單筆請求或交易的詳細執行路徑。
這解決了指標與追蹤之間常見的斷裂問題:
- 指標告訴你哪裡有異常。
- 追蹤告訴你某一次請求為什麼異常。
- 範例資料則提供從指標跳到追蹤的橋樑。
對大規模系統而言,這能明顯改善疑難排解體驗。
從動機到解法
Taboola 將前述需求對應到新的指標函式庫能力。
可聚合直方圖的解法
需求:
- 支援可聚合的直方圖。
- 支援傳統直方圖或原生直方圖。
- 分位數在查詢時計算。
- 可以跨執行個體聚合。
解法方向:
- 使用支援直方圖的函式庫。
- 避免用戶端摘要分位數。
- 讓 Prometheus 在查詢時根據直方圖 bucket 計算 p99、p95 等分位數。
這樣才能正確回答:
- 整體 p99 延遲是多少?
- 某服務所有執行個體的延遲分布如何?
- 不同維度聚合後的延遲是否仍正確?
Prometheus 直方圖
Prometheus 直方圖的價值在於:
- 每個觀測值會落入對應 bucket。
- Prometheus 可以透過 bucket 累積分布計算分位數。
- 直方圖可以跨執行個體、Pod、區域或服務聚合。
- 適合用於延遲、請求耗時、酬載大小等分布型指標。
相較於摘要:
- 摘要的分位數多在用戶端計算,不易聚合。
- 直方圖的分位數可在 PromQL 查詢時計算,較適合大規模聚合。
語意化名稱與標籤的解法
需求:
- 指標函式庫必須支援指標名稱。
- 指標函式庫必須支援標籤。
- 指標應該用語意化方式表達,而不是依賴通用名稱與
_label_0這類標籤。
解法方向:
- 改用支援名稱與標籤的函式庫。
- 讓指標名稱與標籤符合 Prometheus 與 OpenTelemetry 的資料模型。
錄製規則可擴展性的解法
需求:
- 降低通用指標名稱造成的錄製規則複雜度。
- 讓錄製規則更具語意、更容易維護。
- 避免所有計數器或直方圖都塞到同一個指標名稱。
解法方向:
- 透過語意化名稱與標籤重構指標。
- 讓錄製規則可以依照具體指標名稱撰寫。
範例資料整合的解法
需求:
- 指標函式庫必須支援範例資料。
- 指標能與追蹤整合。
- 異常指標可以向下深入追蹤資料。
解法方向:
- 選用支援範例資料整合的檢測函式庫。
OpenTelemetry
Taboola 選擇 OpenTelemetry 作為新的指標檢測方向。
OpenTelemetry 能支援本次遷移所需的主要使用情境:
- 傳統直方圖
- 原生直方圖
- 語意化指標名稱
- 標籤 / 屬性
- 範例資料整合
- 與追蹤的整合
選擇 OpenTelemetry 的原因包括:
- 功能符合需求。
- 社群活躍。
- 生態持續發展。
- Taboola 已經在追蹤使用 OpenTelemetry。
- 可統一指標與追蹤的檢測方向。
遷移需求
由於 Taboola 的指標規模很大,而且既有儀表板、告警、錄製規則已經大量依賴舊有指標,因此遷移不能採用一次性切換。
主要需求包括:
- 透明遷移
- 向後相容
- 平行驗證
- 易於回滾
透明遷移
遷移過程應盡可能對使用者透明。
也就是:
- 服務團隊不應被迫一次改完所有指標。
- 現有儀表板不應立刻失效。
- 現有告警不應因命名改變而全部重寫。
- 新函式庫應該能逐步導入。
向後相容
必須保留舊有指標的相容性。
原因包括:
- 舊儀表板仍在使用。
- 舊告警仍在使用。
- 錄製規則可能還依賴舊版命名。
- 系統規模太大,無法一次完成全部切換。
平行驗證
新舊指標必須能並行一段時間,以便比較:
- 數值是否一致。
- 基數是否可控。
- 儀表板是否符合預期。
- 錄製規則是否正確。
- 告警行為是否合理。
易於回滾
遷移過程必須能快速回滾。
如果新指標函式庫在某些服務中出現問題,需要能透過設定或部署方式快速切回舊行為,避免影響可觀察性穩定性。
決策
Taboola 的決策是:
未來新指標全面採用 OpenTelemetry
也就是未來新的指標檢測以 OpenTelemetry 為主。
這個決策不代表立刻移除所有舊 Dropwizard 指標,而是以漸進式方式讓新指標往 OpenTelemetry 遷移,同時維持舊系統可用。
解法:遷移方案
簡報中的方案重點包括:
- 平行驗證
- 易於回滾
- 將埠號作為設定
- 全面推展
- 命名向後相容
- 友善介面與快取
- 更多 Taboola 內部特色
整體策略是:先建立能同時支援新舊指標的基礎設施,再逐步導入與驗證。
平行驗證
平行驗證是這次遷移的重要策略。
其核心概念是:
- 新指標與舊指標同時存在。
- 使用者可以比較兩者輸出是否一致。
- 在確認沒有差異或差異可接受後,再逐步切換。
- 如果新版本有問題,可以回到舊行為。
這對大規模可觀察性系統很重要,因為指標本身就是營運與除錯基礎。如果指標遷移造成資料錯誤,會直接影響告警、儀表板與事件處理。
易於回滾:將埠號作為設定
為了讓回滾容易,Taboola 將埠號作為設定。
這代表:
- 可以透過設定切換指標端點。
- 新舊指標可以用不同埠號或端點暴露。
- 如果新函式庫出現問題,可以快速切回舊端點。
- 遷移不需要每次都改動大量程式碼。
這種設計讓推展與回滾都更可控。
全面推展
全面推展不是一次性全面切換,而是在滿足以下條件後逐步擴大:
- 新指標函式庫功能穩定。
- 舊指標相容性可接受。
- 平行驗證結果符合預期。
- 回滾路徑明確。
- 使用者文件與支援流程準備完成。
在大型組織中,技術遷移的成功不只取決於函式庫是否正確,也取決於採用流程是否順暢。
命名向後相容
Prometheus 新函式庫的後綴慣例
Prometheus 新函式庫會強制或遵循特定後綴慣例,例如:
- 計數器:
_total - 摘要:
_count、_sum,bucket 可能沒有額外後綴 - 儀表:沒有後綴
例如,某個舊版指標:
SERVICE_counter
如果被視為計數器,可能會輸出成:
SERVICE_counter_total
這會破壞既有儀表板、告警與錄製規則。
Taboola 的舊版命名慣例
Taboola 既有指標有自己的命名慣例,例如:
SERVICE_counter
因此,若直接套用 Prometheus 新函式庫的後綴慣例,會導致向後相容問題。
解法:將舊版指標全部以儀表輸出
Taboola 的解法是:
將所有舊版指標以儀表輸出
因為儀表沒有後綴,因此可以保留原本名稱。
例如:
SERVICE_counter
若作為計數器輸出,會變成:
SERVICE_counter_total
但若作為儀表輸出,則可維持:
SERVICE_counter
這樣能讓舊儀表板、告警與錄製規則繼續運作。
取捨
這個做法的目的不是重新定義指標語意,而是為了舊版相容性。
也就是:
- 新指標走正確的 OpenTelemetry / Prometheus 命名慣例。
- 舊指標為了相容性保留舊名稱。
- 過渡期間同時支援新舊世界。
友善介面與快取
新的檢測函式庫需要提供友善介面,讓開發者容易使用。
這包括:
- 建立指標的 API 要簡單。
- 使用標籤要直覺。
- 避免重複建立相同指標。
- 透過快取降低檢測額外負擔。
- 減少開發者誤用指標 API 的機會。
對大型組織來說,函式庫的開發者體驗很重要。
如果介面太難用,團隊會傾向繼續使用舊方式,導致遷移失敗。
更多 Taboola 內部特色
Taboola 在 OpenTelemetry 基礎上,加入符合內部需求的能力。
通用標籤自動套用
常見標籤會自動套用,例如:
domainenvservice
這樣可以減少開發者手動加標籤的負擔,也能提高指標一致性。
健康度指標
系統會提供健康度相關指標,例如:
taboola_service_uptime_millis
這類指標可用於:
- 服務健康狀態觀察
- 上線時間追蹤
- 平台層級儀表板
- 告警基準線
高基數軟性保護
新函式庫提供高基數軟性保護。
目的是避免開發者不小心將高變異值放進標籤,造成:
- 時間序列爆炸
- Prometheus 負載增加
- 儲存成本上升
- 查詢效能下降
- 儀表板或告警變慢
常見高基數風險包括:
- 使用者 ID
- 請求 ID
- 工作階段 ID
- 動態網址
- 無界限錯誤訊息
- 任意標籤值
指標黑名單
支援指標黑名單。
用途包括:
- 停用問題指標。
- 避免不必要或高成本指標被輸出。
- 在不改應用程式碼的情況下降低可觀察性負載。
- 提供緊急止血手段。
動態指標名稱改寫
支援動態指標名稱改寫。
這可以用於:
- 舊版名稱對應
- 命名修正
- 相容舊系統
- 統一不同服務的命名格式
- 遷移期間調整指標輸出
發布結果
簡報中列出的遷移需求,大多已達成:
- ✅ 透明遷移
- ✅ 向後相容
- ✅ 平行驗證
- ✅ 易於回滾
其中「透明遷移」標註了警示符號,代表雖然大致達成,但實務上仍可能有一些遷移摩擦或例外情況。
整體來看,這次發布的重點是降低組織導入成本,而不是只完成技術替換。
採用推廣
技術遷移不只需要正確的函式庫,也需要讓開發者願意採用。
Taboola 採取多種採用推廣策略。
文件與宣傳
推廣方式包括:
- 使用文件
- Slack 公告與推廣
- 內部技術分享
@Deprecated註記
這些做法讓團隊知道:
- 新函式庫如何使用。
- 為什麼要遷移。
- 舊 API 已經不再建議使用。
- 遷移時遇到問題可以找誰。
主動建議與早期支援
推廣過程中也包括:
- 在適當時機主動建議採用
- 對早期採用者提供友善支援
- 根據回饋快速迭代
這代表平台團隊不是單向發布規範,而是與早期採用者合作,根據回饋快速調整。
這對內部平台產品很重要,因為:
- 早期使用者會發現真實問題。
- 友善支援能降低導入阻力。
- 快速迭代能建立信任。
- 成功案例能帶動後續採用。
自動化 PR 審查
Taboola 也透過自動化 PR 審查偵測舊版指標使用情況。
這可以在程式碼審查階段提醒開發者:
- 不要再使用舊指標 API。
- 改用新的 OpenTelemetry-based 檢測方式。
- 避免新的舊版指標繼續增加。
這是一種把採用政策自動化的做法。
三個月內的使用情況
簡報最後提到「三個月內的使用情況」,表示在推廣後觀察三個月內的採用情況。
雖然簡報文字抽取中未包含具體圖表數字,但從脈絡來看,這一頁用來展示:
- 新函式庫的採用成長。
- 舊版指標使用下降。
- 團隊遷移進度。
- 推廣策略的實際效果。
這也說明可觀察性函式庫遷移需要追蹤採用指標,而不是只看發布是否完成。
總結
這場分享說明 Taboola 如何從 Dropwizard 指標系統遷移到以 OpenTelemetry 為基礎的指標檢測。
核心問題不是單純更換函式庫,而是解決大規模指標系統在演進中遇到的結構性問題:
- Dropwizard 摘要指標難以跨執行個體聚合。
- 用戶端 p99 不適合用來計算整體 p99。
- 以點號分隔的指標名稱不符合現代 Prometheus 標籤模型。
- 通用指標名稱造成錄製規則可擴展性問題。
- 指標與追蹤需要透過範例資料串接。
- 大型組織遷移必須保留向後相容。
- 新舊指標需要平行驗證。
- 回滾必須容易。
- 採用推廣需要文件、宣傳、支援與自動化治理。
Taboola 最終選擇 OpenTelemetry,因為它同時支援:
- 傳統直方圖
- 原生直方圖
- 語意化名稱與標籤
- 範例資料
- 活躍社群
- 與既有追蹤基礎設施整合
這次遷移的關鍵經驗是:
在大規模可觀察性系統中,指標檢測函式庫不只是開發工具,而是平台治理、資料模型、查詢效能與組織採用策略的共同基礎。
從 Dropwizard 到 OpenTelemetry,真正的轉變不只是 API,而是從舊版指標模型走向更語意化、可聚合、可治理、可與追蹤整合的可觀察性基礎。