似乎越来越多的技术管理者开始谈论将一个Mono-Repo(传统的将项目所有的代码放在一个仓库里)拆分成多个更小的Mono-Repo这种更”细碎“的代码管理策略。这种策略的兴起和微服务架构的流行有很大的关系。微服务架构要求系统将服务切分成可独立维护和运行的服务模块,模块间可以通过RESTRPC的方式进行交互。这样一来,每个服务模块都可以拥有自己专属的代码仓库,即自己的Repo,以方便进行独立的开发和维护。

判断一摞代码文件是否应该被拆分出来存储到一个独立的Repo的方法大致有以下几种:

  •  It is a business domain。比如一个进销存系统,货品管理(CRUD)由于是进销存业务操作的基础,可以为其创建一个Repo。如何去划分business domain, 我们可以参考Domain Driven Development (DDD)中的方法。
  • 技术差异性。如果使用的技术和其他服务实现代码差异较大(比如使用了不同的编程语言,不同的技术框架或不同的API请求规范),那么我们也可以为其创建一个独立的Repo。
  • 可共享可复用。如果可以被多个项目使用(比如基础服务模块,实用工具类,中间件),那么我们也应该为其创建一个独立的Repo。

将代码分门别类地存放到独立的Repo的好处是显而易见的:

  • 由于Function-call-chain被缩短了,end-to-end的测试更容易实现。
  • 由于代码库容量变小了,代码更容被维护,更新和部署也会更迅捷。
  • 为了让一个模块可以在独立的Repo中维护,工程师们在编码时需要更充分地考虑模块间的耦合问题。这样一来,模块间的交叉影响会更小。

当然,事情总有两面性,这种策略也会带来一些麻烦:

  • 在规模较小的团队里,这种策略会增加工程师的日常工作量。一个工程师可能需要同时维护多个独立的Repo。这有可能影响工作效率,同时还有可能增加错误率。
  • 每一个独立的Repo都有自己的版本演进节奏。由于没有统一的版本号,每一个模块的版本都需要记录与其相关(调用或被调用)的模块兼容版本。随着模块数量的增加,以及各模块版本的不断演进,这个记录会变得无比庞大。一旦记录出错,就可能造成服务失效。
  • 为了进行系统集成测试,我们需要重新打包来自独立Repo的代码,这个过程很可能费时费力。当然我们可以把end-to-end的测试做好,来保证代码的可靠性。

简单总结一下,将项目的Mono-Repo拆分成若干独立的Repo的策略对于基于微服务架构的系统是很有价值的。如何对代码进行拆解没有一个黄金标准。我们需要结合业务场景,也需要结合团队规模,代码更新频次、可维护性的需求层次来进行判断。也许,随着产品的演进,我们需要通过重构代码来实现更合理的代码拆解。

发表评论

电子邮件地址不会被公开。 必填项已用*标注