Behind the Scenes: Block 450 JVM Repositories Into Monorepo to Reduce Dependency Drift

TL;DR · AI 摘要
Block 将 450 个 JVM 仓库迁移至单体仓库,以减少依赖漂移并提升开发效率。
核心要点
- Block 将 450 个 JVM 仓库合并为一个单体仓库,以减少依赖漂移。
- 迁移后,每周支持约 8,800 次构建,p90 CI 时间缩短至 10 分钟。
- Block 开发了自定义 IntelliJ 插件,优化了 IDE 工作流和构建性能。
结构提纲
按章节快速跳转。
思维导图
用一张图看清主题之间的关系。
查看大纲文本(无障碍 / 无 JS 友好)
- Block JVM 仓库迁移至单体仓库
- 背景与挑战
- 多仓库架构下的依赖管理复杂性
- 依赖版本漂移与运行时不兼容
- 迁移成果
- 每周支持 8,800 次构建
- p90 CI 时间缩短至 10 分钟
- 技术实现
- 自定义 IntelliJ 插件
- Gradle 插件与构建优化
金句 / Highlights
值得收藏与分享的关键句。
The monorepo now supports approximately 8,800 builds per week, with p90 CI times of around 10 minutes on a reliably green main branch.
The monorepo enables atomic updates across services in a single commit, while resolving shared dependencies directly from source.
What started as a complex, large-scale migration became a step-change in developer experience: a modern, cohesive codebase with an optimized IDE workflow.
幕后揭秘:将 450 个 JVM 仓库合并到单体仓库以减少依赖漂移 - InfoQ
InfoQ 首页 News 幕后揭秘:将 450 个 JVM 仓库合并到单体仓库以减少依赖漂移
架构与设计
为自主可靠性而设计:将 AI 嵌入到您的可观测性堆栈中(网络研讨会,6 月 25 日)
幕后揭秘:将 450 个 JVM 仓库合并到单体仓库以减少依赖漂移
2026 年 6 月 19 日 5 分钟阅读
作者:
- Leela Kumili
#### 为 InfoQ 撰写文章
激发你的好奇心。
帮助 55 万+ 全球
高级开发人员
每月保持领先。
联系我们
收听这篇文章 -
0:00
音频准备播放
你的浏览器不支持音频元素。
正常
1.25x
1.5x
喜欢
新下拉阅读列表
- 阅读列表
Block, Inc. 描述了从多仓库架构向单体仓库的大规模迁移,以解决后端系统中日益增长的协调和依赖管理挑战。该计划将大约 450 个基于 JVM 的仓库合并到一个代码库中,以简化跨服务开发,提高依赖可见性,并减少分布式系统中的操作摩擦。
根据 Block 工程团队的说法,目前的单体仓库每周支持大约 8,800 次构建,主分支上 p90 的 CI 时间约为 10 分钟。
在之前的多仓库模型中,服务和共享库分别维护在不同的仓库中,允许团队独立运作,但随着时间的推移,引入了越来越多的协调复杂性。这种模型导致了依赖版本漂移,重复的升级工作,以及 JVM 服务之间运行时不兼容的风险增加,包括经典的钻石依赖惊喜。
Block 的高级工程经理 Gabor Pap 提到,
最初这是一次复杂的大规模迁移,但最终成为开发者体验的一个重大飞跃:一个现代、连贯的代码库,优化的 IDE 工作流程,显著更快的 CI,以及为长期速度奠定的基础。其影响远远超出了工具本身。
在多仓库模型中,依赖不匹配和跨仓库的更改通常需要跨团队的协调部署。而单体仓库允许在单次提交中对服务进行原子更新,同时直接从源代码解决共享依赖,而不是通过独立版本的内部库。
为了支持这种规模,Block 开发了一个自定义的 IntelliJ 插件,仅加载工程师所需的项目,采用合并队列以在高提交量下保持主分支的稳定,并投资于共享的 Gradle 插件、基于依赖图的构建范围定义以及 git 性能调优,包括探索稀疏检出,随着仓库的增长。
Yissachar Radcliffe:在多仓库(polyrepo)中,依赖管理变得难以控制。我们经常要处理破坏性变更,这些变更有时会表现为运行时失败。尝试向下游消费者推出一个库或 API 变更通常需要巨大的努力。我们探索了其他替代方案,希望通过增强对破坏性变更的防护来继续使用多仓库模型,但最终认为单仓库(monorepo)能更好地解决问题,并且更全面地改善我们的开发体验。
InfoQ:你们如何构建和使用依赖图,以在单仓库中高效地限定构建、测试和代码变更的范围?
Yissachar Radcliffe:我们会查看 PR 中修改了哪些文件,然后将其与我们的项目依赖图进行比对,以确定需要构建哪些项目以及如何构建。大致来说,我们将变更分为三类:变更直接影响某个项目(例如项目本身的文件变更)、变更间接影响某个项目(例如项目所依赖的上游项目的变更)、变更属于全局变更,应导致整个单仓库构建(某些核心文件的变更)。这种分类确保我们构建所有必要的内容以防止破坏性变更,同时也使我们能够根据变更类型调整构建内容。例如,对于间接变更,我们可以跳过一些不可能失败的 CI 检查。
InfoQ:自定义的 IntelliJ 插件是开发体验的关键部分。它是如何确定在工作流中包含或排除哪些项目的?工程师在需要时如何覆盖这些默认设置?
Yissachar Radcliffe:工程师会指定他们正在工作的项目,我们只将这些项目加载到 IntelliJ 中。在后台,我们会动态地将依赖项目的项目引用替换为已发布的 JAR 引用。这有助于保持 IDE 的快速和可控,避免 Gradle 配置阶段变慢。这种方法的开源版本可以在 https://github.com/joshfriend/spotlight 和 https://github.com/block/artifact-swap 上找到。
InfoQ:随着单仓库的规模扩大,你们是如何在优化 CI/CD(通过选择性构建、缓存和变更检测等技术)的同时,保持清晰的所有权和服务边界?
Yissachar Radcliffe:我们使用 Block 的仓库所有权工具来为每个项目定义所有者。团队负责其项目代码,而单仓库团队则负责通用的构建工具。我们还开发了一套强大的 Gradle 常规插件,定义了常见的模块类型,例如 proto 模块、服务模块、库模块等。这些不仅有助于我们管理依赖图(例如,服务模块不能依赖另一个服务模块),还使我们能够轻松地将改进措施推广到所有项目。
InfoQ:自从迁移到单仓库后,AI 辅助开发工具是否改变了工程师在代码库中导航或工作的方式?在如此大规模的代码库中,出现了哪些新的挑战?
Yissachar Radcliffe:最大的变化是,IDE对我们来说不再那么重要,因为许多工程师将AI辅助工具集成到他们的开发流程中。由于可以访问大量上下文信息,代理在我们的单体仓库中表现良好,而我们对标准化的押注也得到了回报,因为代理可以遵循非常清晰的路径。我们的扩展挑战与AI之前基本相同(构建性能、Git可扩展性等);我们现在只是看到代码更改的频率更高了。
InfoQ:回顾过去,迁移过程中遇到的最困难或最意外的挑战是什么?在什么情况下,您会建议团队不要采用单体仓库?
Yissachar Radcliffe:由于难以保持我们期望的开发者体验,迁移所花费的时间比最初计划的要长。随着单体仓库的不断增长,我们不断发现新的CI可扩展性挑战;在引入更多项目之前,这些问题必须得到解决。此外,还有一些多仓库项目,它们的构建速度非常慢,或者有非常定制的设置,需要大量努力进行优化之后才能引入。虽然这些情况只占所有项目的一小部分,但它们消耗了我们大量的注意力。
无论是单体仓库还是多仓库,都需要对平台团队进行适当的投资,才能蓬勃发展,但在这两个选择中,单体仓库在被忽视时会受到更大的影响。如果你无法承诺为支持单体仓库的平台团队提供足够的资金,那么使用多仓库可能更好,因为团队可以改进自己的代码库,而不会因为行为不当的兄弟项目而受到惩罚。单体仓库最适合结构相似的项目。如果你的项目混合了不同的语言、框架和风格,单体仓库可能不会带来显著的好处,可能不值得投资。
作者部分的主包装器
关于作者
部分标题
每个作者的主包装器
#### Leela Kumili
显示更多
显示更少
#### 此内容属于大型项目主题
##### 相关主题:
- 开发
- 架构与设计
- DevOps
- IntelliJ IDEA
- JVM
- 平台工程
- 大型项目
- 持续集成
- 插件
- Java
- 分布式系统
- 持续部署
- 构建系统
- IDE
- 相关编辑
- 相关赞助商 理解AI代理安全
- 相关赞助商 使用Promptfoo自信地测试、评估和红队你的LLM应用——发现回归、基准模型,并更快地推出高质量的AI功能;今天开始测试你的提示。了解更多。
InfoQ 时事通讯
每周内容回顾,每星期二发送。加入超过25万名高级开发者的社区。查看示例
我们保护您的隐私。