Ohhnews

分类导航

$ cd ..
InfoQ Java原文

Block公司合并450个JVM仓库为单一仓库以减少依赖漂移

#block#monorepo#jvm#依赖漂移#持续集成

幕后:Block 将 450 个 JVM 仓库合并为单体仓库以减少依赖漂移

2026 年 6 月 19 日 · 5 分钟阅读

作者:Leela Kumili

Block, Inc. 已公开描述其在其 Cash App 和 Square 工程组织中,从多仓库架构向单体仓库的大规模迁移,以应对后端系统日益增长的协调和依赖管理挑战。该计划将约 450 个基于 JVM 的仓库整合到一个代码库中,以简化跨服务开发、提高依赖可见性,并减少分布式系统中的运营摩擦。

据 Block 工程团队介绍,该单体仓库目前每周支持约 8800 次构建,p90 CI 时间大约为 10 分钟,主分支保持稳定的绿色。在之前的多仓库模式下,服务和共享库分别维护在独立的仓库中,虽然允许团队独立运作,但随着时间的推移引入了日益复杂的协调难题。该模式导致了依赖版本漂移、重复的升级工作,以及 JVM 服务之间运行时不兼容风险的增加,包括经典的菱形依赖问题。

Block 高级工程经理 Gabor Pap 提到:

最初作为复杂的大规模迁移,最终成为了开发者体验的跨越式进步:现代化的、凝聚的代码库,优化的 IDE 工作流,显著更快的 CI,以及为长期速度构建的基础。影响远超工具层面。

在多仓库模式下,依赖不匹配和跨仓库变更通常需要团队之间的协调部署。而单体仓库允许通过单个提交实现跨服务的原子更新,同时直接从源码解析共享依赖,而不是依赖独立版本化的内部库。

为了支持这一规模,Block 构建了 自定义 IntelliJ 插件,仅加载工程师所需的项目;采用合并队列以在高提交量下保持主分支稳定;并投入资源到共享 Gradle 插件、基于依赖图的构建范围限定以及 Git 性能调优(包括探索稀疏检出),随着仓库的增长不断优化。

InfoQ 采访了 Yissachar Radcliffe,了解迁移的细节。

InfoQ:是什么扩展性或协调挑战使得多仓库模式变得不可持续?在决定迁移到单体仓库之前,你们评估了哪些替代方案?

Yissachar Radcliffe:多仓库模式中的依赖管理已变得无法管理。我们不断处理破坏性变更,有时会表现为运行时故障。尝试向下游消费者推出库或 API 变更往往需要付出巨大努力。我们曾探索过一些替代方案,希望通过增强对破坏性变更的防护来继续使用多仓库模式,但最终认定单体仓库能更好地解决问题,并普遍改善我们的开发者体验。

InfoQ:你们如何构建和使用依赖图来高效地在单体仓库中限定构建、测试和代码变更的范围?

Yissachar Radcliffe:我们会查看 PR 中修改了哪些文件,然后对照项目依赖图,确定哪些项目需要构建以及如何构建。大致上,我们将变更分为三类:变更直接影响项目(例如项目自身的文件变更),变更间接影响项目(例如上游项目的变更,而该项目依赖该上游项目),以及全局变更(某些核心文件变更,应触发整个单体仓库的构建)。这种分类确保我们构建所有必要的部分以防止破坏性变更,同时允许针对每种变更类型调整构建内容。例如,对于间接变更,我们可以跳过那些不可能失败的 CI 检查。

InfoQ:自定义 IntelliJ 插件是开发者体验的关键部分。它如何确定工作流中应包含或排除哪些项目?工程师在需要时如何覆盖这些默认设置?

Yissachar Radcliffe:工程师指定他们正在工作的项目,我们只将那些项目加载到 IntelliJ 中。在幕后,我们会动态地将项目引用替换为已发布 JAR 的引用(针对依赖项目)。这样保持 IDE 快速且可管理,避免缓慢的 Gradle 配置阶段。可用的开源版本包括 https://github.com/joshfriend/spotlighthttps://github.com/block/artifact-swap

InfoQ:随着单体仓库的扩展,你们如何通过选择性构建、缓存和变更检测等技术,在优化 CI/CD 的同时维护清晰的代码所有权和服务边界?

Yissachar Radcliffe:我们使用 Block 的仓库所有权工具为每个项目定义所有者。团队负责其项目代码,而单体仓库团队负责通用构建工具。我们还开发了一套强大的 Gradle 约定插件,定义了常见的模块类型,例如 proto 模块、服务模块、库模块等。这不仅有助于保持依赖图的可管理性(例如服务模块不能依赖另一个服务模块),还允许我们轻松地向所有项目推出改进。

InfoQ:迁移到单体仓库后,AI 辅助开发工具是否改变了工程师浏览或处理代码库的方式?在这一规模下又出现了哪些新挑战?

Yissachar Radcliffe:一个重大变化是,随着许多工程师将 AI 辅助工具融入开发工作流,IDE 已不再是我们的关注焦点。Agent 在我们的单体仓库中表现良好,因为它们能访问大量上下文,而我们对标准化的投入也获得了回报——Agent 拥有了明确的路径可以遵循。我们的扩展挑战基本与 AI 出现前相同(构建性能、Git 可扩展性等),只是现在代码变更的速率更高了。

InfoQ:回顾这次迁移,你们遇到的最困难或最意外的挑战是什么?在什么情况下你会建议团队不要采用单体仓库?

Yissachar Radcliffe:迁移花费的时间比原计划更长,原因是难以维持期望的开发者体验。我们不断在单体仓库增长过程中发现新的 CI 可扩展性挑战,这些挑战必须在引入更多项目之前解决。此外,一些多仓库项目构建速度极慢或设置非常定制化,需要投入大量精力进行优化后才能迁移进来。虽然这些案例只占项目总数的一小部分,却消耗了我们过多的精力。

无论是单体仓库还是多仓库,都需要对平台团队进行适当投入才能蓬勃发展;但在这两种选择中,单体仓库在缺乏维护时尤其容易出问题。如果你无法承诺充分资助一个平台团队来支持单体仓库,那么多仓库可能更适合你——团队可以在自己的代码库中改进,且不会因为行为不当的兄弟项目而受到惩罚。单体仓库也最适合形态相似的项目。如果你的项目混杂了多种语言、框架和风格,单体仓库可能无法带来显著收益,甚至不值得投入。

关于作者

[LOADING...]

Leela Kumili

Leela 是星巴克的首席软件工程师,在构建可扩展的云原生系统和分布式平台方面拥有深厚专业知识。她负责奖励平台(Rewards Platform)的架构、交付和卓越运营,领导系统现代化、可扩展性提升和可靠性增强等工作。除了技术领导力外,她还担任组织的 AI 倡导者(AI Champion),识别使用基于 LLM 的工具提升开发者生产力和工作流的机会,并建立 AI 采纳的最佳实践。她热衷于构建生产就绪系统、提升开发者体验,并指导工程师在技术和战略方面成长。她的兴趣领域包括平台工程、分布式系统、开发者生产力,以及将技术解决方案与业务和产品目标相结合。


此内容属于 Java 主题