话题背景
在软件开发领域,代码仓库的管理方式对项目的效率和协作有着重要影响。
随着项目结构的日益复杂和开发挑战的不断增长,传统的单一代码库(Monolith)在应对多项目、多库和多服务的情况下显得力不从心,正是在这个背景下,Monorepo(微服务大仓)和Multirepo(微服务多仓)的概念应运而生。
你怎么看待大小仓之争?
今天就让我们来一起聊聊“为什么要用大仓,monorepo比multirepo好在哪里?”
鹅厂工程师的看法
@cheater-CSIG模型开发组长▼
我写过一篇文章《单一大仓实践与工业化》。里面讲到大仓主要好处是:
- 能在同一个地方建设辅助开发者的工具
- 保证开发者对整个项目的可见性,易于获取性
- 能批量集中地修复任何一类工程问题。
有人说,他们用了monorepo,实际上是一个超级大shi山。但是,同样是shi山,集中在一起,就比散落在很多地方的无数小shi堆,治理起来要容易一些。在monorepo下,我们能评估治理的工作量,如果是无数小shi堆儿,根本就没法治理了。
@tide-CSIG后台开发工程师▼
个人感觉,monorepo是面向管理者的,是为了简化项目管理者的管理难度,增加对开发过程的控制力度的工具。
有些一体性强的超大单体应用可能还比较适合,但是对于一个追求灵活、快速迭代的分布式系统强行使用就是灾难。
@thom-PCG后台开发工程师▼
分布式和集中式类似的区别,集中在一个点做好 ,程序员对代码有理想的追求是值得肯定的,另外上面的都想一次性就做好,每次都更新到最好的版本,最好的代码,所以可能倾向选择monorepo。
但是一般理想很美好。显示很骨感, 通常我们可能都在快速迭代,寻找新的业务增长点,这个时候
multirepo容错性更好,迭代更快各有优劣~开发好了,就可以一直不改,不动了。
结论:multirepo和monorepo都是工具,作为工程师把工程做好,业务做好才是王道,谁优谁劣都要根据一定的应用场景
@les-CSIG后台开发工程师▼
换一个角度,多仓库 + 仓库多版本,仓库之间又常常存在依赖关系,这可以将多仓管理规约到依赖管理问题上,而后者又可以规约为3-sat问题,众所周知,这是NPC问题…
也就是说,带有多版本的multirepo,使用者容易陷入版本泥潭,脑容量不够用… 而规避这个由管理模式导致的依赖管理问题,一个简单直接的方式:只用一个仓库😋
@lucasz-WXG前端开发工程师▼
大仓可能是一种重构后的选择,也可能是一开始的选型方案,因为业务下的项目呈现是动态的。
主要优势是能够更低成本统一和维护 多应用的工程化方案,当然也会带来工程复杂度的上升。因此判断条件无非是收益和成本的权衡,以下是可以去考量的几个点:
- 人员在多个单仓来回开发的上下文差异,导致切换仓库开发的成本越高,大仓收益越高
- 工程化方案的中配置即代码的部分占比越大,即工程通过代码复用,大仓收益就更高
- 复用更统一先进的工程化方案的收益 VS 分散开独立支撑业务小步快跑独立性的收益
- 分散的单仓间工程化统一的难度 VS 集中力量应对工程复杂度提升的难度
@folger-CSIG前端开发▼
大仓担心CI,试试CNB,现在在公测中~
@jom-PCG客户端开发▼
大仓(Monorepo)与多仓(Multirepo)有各自的优缺点,两者往往可以互补,具体选择哪个取决于项目的规模、具体需求、以及团队的分布,从Monorepo的优缺点来讲:
优势:
- 复用工程化基建:可以统一工程化配置和DevOps流程,包括但不限于Lint规则、构建脚本、测试、CICD流程等,基建的事情只需要做一遍,包括后续统一改造和升级,从而降低多项目维护成本。
- 利于代码复用:由于所有代码都在一个仓库内,依赖的管理可以更加简化和一致(本地npm包,自动解决依赖关系),依赖的安装也更高效(共同依赖只会安装一次)。这样带来的好处就是极大降低代码复用成本,比如需要抽离新的「复用代码」,创建个npm模块子项目就能直接进行开发、调试,而如果是Multirepo,需要手动进行npm link或者npm发布,还要手动处理依赖关系,后续的版本升级也比较繁琐,久而久之,就会降低大家做此类抽离工作的积极性。
- 版本控制更统一:各个项目和模块可以更容易保持版本的一致性,所有的依赖关系和代码变更可以在同一个提交中进行更新,能确保整个代码库的一致性,这样也更利于做跨项目的自动化工作流。
- 团队协作更简单:代码的可见性高,有助于跨团队的知识共享和代码审查,同时团队成员之间的协作也更加顺畅。
不足:
- 规模和性能问题:随着项目和代码量的增长,clone和构建的时间可能会拉长,互相之间的影响也会被放大,任何变更都可能对其他项目产生连锁反应,增加了变更管理的复杂性,需要更谨慎的规划和协调。比如A项目修改了BCD都依赖的公共模块,则需要BCD都经过完整的验证才能一起发布上线,而不是BCD先保留旧版的公共模块,按照自己的节奏实施升级;
- 复杂度更高:对于小团队和项目,大仓可能会引入没必要的复杂性;
- 工具链要求高:对工具和基础设施提出了更高要求,需要构建和维护适合大型代码库的复杂工具链和基础设施。比如使用lerna,rush 或者 Nx 来做Monorepo,要与司内各基建平台打通就不是那么简单。
综上,Monorepo可能更适合大型组织或需要紧密协作的大团队,而Multirepo则更适合独立发展且相互依赖性较小的项目。
@shugen -CSIG应用开发▼
对基础依赖的统一管理和升级很舒服,也更方便做底层能力封装,CI/CD 方便也简单不少。