![]()
作者 | Leela Kumili
譯者 | 張衛(wèi)濱
Block,Inc. 介紹了一次大規(guī)模的 從 polyrepo 架構向 monorepo 遷移的實踐,覆蓋其 Cash App 與 Square 工程組,以應對后端系統(tǒng)日益增長的協(xié)調與依賴管理挑戰(zhàn)。該計劃將約 450 個基于 JVM 的倉庫合并為單一的代碼庫,其目標是簡化跨服務開發(fā)、提升依賴可見性并減少分布式系統(tǒng)的運行摩擦。
據(jù) Block 工程團隊稱,該 monorepo 目前每周約支持 8800 次構建,在保持 main 分支穩(wěn)定的前提下,p90 CI 時間約為 10 分鐘。
在此前的 polyrepo 模型下,服務與共享庫分布在獨立倉庫中,雖然團隊可以獨立工作,但隨著時間推移,協(xié)調的復雜度不斷增加。該模型導致依賴版本漂移、重復性的升級工作,以及跨 JVM 服務的運行時不兼容風險,包括典型的鉆石依賴(diamond dependency)問題。
Block 的高級工程經理 GaborPap 曾經提到:
這最初是一次復雜的大規(guī)模遷移,但最終在開發(fā)者體驗上帶來了飛躍:一個現(xiàn)代且一致的代碼庫、優(yōu)化的 IDE 工作流、顯著更快的 CI,并為長期的敏捷性奠定了基礎。影響遠超工具本身。
在 polyrepo 模型中,依賴不匹配與跨倉庫變動常常需要團隊間協(xié)同部署。monorepo 允許在單次提交中完成跨服務的原子性更新,并優(yōu)先直接從源碼解析共享的依賴,而非依賴獨立版本的內部庫。
為了支撐這樣的規(guī)模,Block 開發(fā)了一個定制的 IntelliJ 插件,支持按需加載工程師需要的項目,采用合并隊列(merge queue)以在高提交量下保持 main 分支的穩(wěn)定,并采用了共享 Gradle 插件、基于依賴圖的構建范圍縮減與 git 性能調優(yōu)(包括探索 sparse checkout)以應對倉庫的增長。
InfoQ 就此遷移采訪了 Yissachar Radcliffe。
InfoQ:是什么樣的擴展或協(xié)調挑戰(zhàn)使得 polyrepo 模型變得難以持續(xù)?在決定遷移到 monorepo 前你們評估了哪些替代方案?
Yissachar Radcliffe:polyrepo 下的依賴管理已經難以為繼。我們不斷面對破壞性的變更,有時它們會以運行時故障的形式出現(xiàn)。向下游消費者發(fā)布庫或 API 變更常常需要巨大的努力。我們曾經評估通過增強對破壞性更改的保護來繼續(xù)保留 polyrepo,但最終認為 monorepo 能更好地解決問題并總體上改善開發(fā)者體驗。
InfoQ:你們如何構建并利用依賴圖來高效地為 monorepo 實現(xiàn)范圍化構建、測試與代碼變更?
Yissachar Radcliffe:我們會查看 PR 中被修改的文件,并將其與項目依賴圖比對,以確定需要構建的項目。整體而言,我們把變更分為三類:直接影響某個項目(例如,項目內部的文件變更)、間接影響某個項目(例如,上游依賴的變更)以及應觸發(fā)整個 monorepo 構建的全局性變更(特定核心文件的變更)。這種分類能夠確保我們會構建所有必要的內容以防止破壞性變更,同時允許針對每類變更調整要執(zhí)行的構建。例如,對于間接變更,我們可以跳過不可能失敗的某些 CI 檢查。
InfoQ:定制的 IntelliJ 插件是開發(fā)者體驗的關鍵。它如何決定在某個工作流中包含或排除哪些項目?工程師如何在需要時覆蓋這些默認配置?
Yissachar Radcliffe:工程師能夠指定他們正在處理的項目,插件會只將這些項目加載到 IntelliJ 中。在幕后,我們會動態(tài)地讓依賴項目使用已發(fā)布的 JAR,以替換項目引用,從而保持 IDE 快速且可管理,避免緩慢的 Gradle 配置階段。類似實現(xiàn)的開源項目可見于 spotlight 與 artifact-swap。
InfoQ:隨著 monorepo 擴展,你們如何在確保選擇性構建、緩存與變更檢測優(yōu)化 CI/CD 的同時保持清晰的所有權與服務邊界?
Yissachar Radcliffe:我們使用 Block 的倉庫所有權工具為每個項目定義所有者(owner)。團隊負責各自項目的代碼,而 monorepo 團隊負責通用的構建工具。我們還開發(fā)了一套強大的 Gradle 約定插件,定義常見的模塊類型(比如,proto 模塊、service 模塊、library 模塊等)。這些插件不僅有助于保持依賴圖可控(例如,service 模塊不能依賴另一個 service 模塊),也便于我們將改進快速推送到所有項目。
InfoQ:遷移后,AI 輔助開發(fā)工具是否改變了工程師在代碼庫中的導航或工作方式?在這種規(guī)模下出現(xiàn)了哪些新挑戰(zhàn)?
Yissachar Radcliffe:主要變化是 IDE 不再是唯一的焦點,許多工程師將 AI 輔助工具納入了開發(fā)流程。由于 monorepo 能提供大量上下文,智能體的表現(xiàn)很好。我們對標準化的投入也得到了回報,因為我們?yōu)橹悄荏w設計了明確的路徑。規(guī)模化挑戰(zhàn)與遷移前大體相同(構建性能、git 可擴展性等),只是現(xiàn)在代碼變更率更高。
InfoQ:回顧遷移過程,最困難或最出乎意料的挑戰(zhàn)是什么?在什么情況下你會建議團隊不要采用 monorepo?
YissacharRadcliffe:遷移耗時比預期更長,因為維持預期的開發(fā)者體驗需要大量的精力。隨著 monorepo 增長,我們不斷發(fā)現(xiàn)新的 CI 可擴展性問題,這些問題需要在繼續(xù)合并更多項目之前得到解決。此外,一些 polyrepo 項目構建非常慢或有高度定制的設置,導入前需要大量的優(yōu)化。盡管這類項目在總數(shù)中占少數(shù),卻消耗了大量精力。
無論是 monorepo 還是 polyrepo,都需要平臺團隊的投入才能成功,但 monorepo 在缺乏維護時更容易崩潰。如果你無法承諾為 monorepo 提供足夠資源支持平臺團隊,polyrepo 可能更適合,讓團隊各自改進自身的代碼庫,同時避免表現(xiàn)不佳的兄弟項目所造成的影響。monorepo 更適合形態(tài)相近的項目。如果你的項目混雜多語言、多框架與多風格,那么 monorepo 帶來的收益可能不足以抵消投入的成本。
查看英文原文:
Behind the Scenes: Block 450 JVM Repositories Into Monorepo to Reduce Dependency Drift(https://www.infoq.com/news/2026/06/block-450-jvm-monorepo-migration/)
聲明:本文由 InfoQ 翻譯,未經許可禁止轉載。
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發(fā)布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.