解決方案
SoundCloud 的 JVMKit 函式庫為數百個內部 Scala、Java、Clojure 與 JRuby 服務提供共用的 JVM 模式——服務骨架、資料庫與 Kafka 整合、指標。隨著採用範圍擴大,平台團隊逐漸無法掌握哪些服務依賴 JVMKit API 的哪些部分,使每次發布都像一場賭博:一次例行更新可能悄悄破壞團隊甚至不知道會受影響的服務。
由於 SoundCloud 的相依性是在每個儲存庫的建置檔中明確宣告的(JVM 用 sbt、Android 用 Gradle、網頁用 npm),團隊用 Zoekt(一套以正規表達式為基礎的程式碼搜尋引擎)為每個儲存庫建立索引,每五分鐘更新一次。對建置檔做一個簡單查詢、列出以 JVMKit 為相依性的項目,就能產生即時的反向相依圖——每個會受 JVMKit 變更影響的服務都自動產生,而非人工追蹤。
有了這張圖,團隊建立了一條驗證流程:對每個相依服務,複製儲存庫、以未修改的狀態編譯並測試以建立基準,然後換入候選的 JVMKit 版本、套用針對已知破壞性 API 變更的腳本化修正,再編譯並測試一次。如果基準通過但候選版本失敗,那麼原因就是 JVMKit 的變更,而不是該服務原本就存在的問題。這項檢查每晚對完整相依集合執行,並在每個拉取請求上對一份更快的允許清單子集執行。
達成了什麼
在發布函式庫之前,對每個呼叫方進行編譯與測試
為何有效
它用自動化、可證偽的檢查取代了人工且容易出錯的流程(發布、等團隊抱怨),並在發布前執行。
先執行未修改的基準,能區分失敗是來自 JVMKit 的變更,還是來自當天原本就已損壞的服務。
將驗證拆分為每晚完整執行與快速的 PR 範圍執行,既能保持回饋迅速,又不跳過完整涵蓋範圍。
反向相依圖是從程式碼產生,而非人工維護,因此隨著服務新增或移除仍能保持準確。
可套用之處
當一個內部函式庫支撐著數百個服務時,不要靠運氣發布——讓相依圖可查詢,並讓 CI 先測試每個下游呼叫方。
後續
JVMKit 持續支撐 SoundCloud 數百個服務與數千個生產執行個體。有了驗證流程後,平台團隊回報 JVMKit 的發布頻率提高,失敗可追溯到特定步驟與特定原因,而不是在下游以無法解釋的故障形式浮現。
追溯依據
參考來源
- Did I Break You? Reverse Dependency Verification SoundCloud Engineering · developers.soundcloud.com ·