多存储库与单存储库的微服务发布管理比较 译文
?译者 |?陈峻
审校 |?孙淑娟
引言:本文从跟踪变更,获悉其不同的版本,以及发布管理的角度,比较了微服务应用多存储库与单存储库方式的差异性。
让我们来设想一个由数十个可持续部署(continuously-deployed)的自治服务所组成的微服务应用。该应用程序的每个服务群都有自己的存储库。它们拥有不同的版本控制方案,并由不同的团队在不断发布着新的版本。那么,由于变更历史分散在这数十个存储库中,我们该如何有效地跟踪变更,获悉其不同的版本,以及管理应用的发布呢?
想必这是任何使用微服务架构的团队,都需要处理的问题。下面,我将和您讨论可以用来管理微服务发布的两种不同方法。
通用方法:一个微服务配一个存储库
目前,使用微服务架构的应用通常会采用multirepo(多存储库)这一最常见的方法,即:
1.?设计一些可被分解为微服务。
2.?为每一个微服务创建一个单独的存储库。
3.?让每个存储库都有一个独立的CI/CD管道,用于将微服务持续部署到生产环境中。
这种细粒度的持续部署形式可以被称为微部署。通过微部署,微服务版本可以被独立地进行部署,而且几乎不需要任何集成测试。
每个微服务都有一个单独的CI/CD管道
可以说,微部署是将代码组织成为多存储库的必然结果。上图展示了目前Semaphore?CI/CD部署微服务的方式。
维护多个发布
持续的微部署非常适合那些由Netflix或Semaphore CI/CD等平台托管的应用。在此类应用中,用户或客户不知道、也并不感兴趣其幕后运行的单个微服务的版本。然而,对于运行在本地(on-premise)的相同应用而言,持续部署并不能起作用。对此,我们只能发布包含了固定在特定版本中的一组微服务。例如,您可以使用Semaphore On-Premise在防火墙的后面,运行全功能版本的Semaphore CI/CD。
针对托管式应用的微部署,应结合产品的本地实例的发布
通常,我们可以按照如下步骤,发布被组织成multirepos的应用:
1.?在每个repo(存储库)中,标记那些有待发布的微服务版本。
2.?针对每个微服务,构建一个Docker镜像,并将微服务的版本映射到镜像标签上。
3.?在单独的测试环境中,使用集成测试、验收测试,甚至是手动测试等方式,全面测试有待发布的版本。
4.?在更新文档之前,检查每个存储库,并为发布的变更日志(changelog),编译相应的变更列表。
5.?识别旧版本所需的各种热修补程序。
6.?发布版本。
鉴于一个应用可以包含数十个微服务(和存储库),我们很容易看出,该发布方式会导致大量重复的管理开销。
使用Monorepos(单存储库)管理发布
显然Multirepos更适合于持续部署。而对于那些非定期、非持续的发布,我们需要将所有微服务集合到一个共享的存储库中。这便是Google、Airbnb和Uber等大公司,多年以来一直使用的Monorepo方法。
Monorepo包含了所有微服务和统一的CI/CD部署管道
Monorepo策略会让微服务感觉更像是一个单体应用,其好处在于:
- 让创建一个发布就像创建某个分支和使用标签一样简单。
- 单个CI/CD流程可标准化测试和部署。
- 更容易实现集成和验收测试。
- 单个Git历史更易于理解,并简化了编写变更日志和更新文档的过程。
由一个CI/CD来统管所有
针对变更的Monorepo模式的主要特点体现在如下方面:
- 由于所有变更都被提交到一处,所以CI(持续集成)服务器会承受更大的压力。我们可以通过使用??基于变更的执行???(change-based execution)或诸如:??Bazel???、??Pants??之类的Monorepo感知工具,来处理此类问题。
- 由于Git没有内置的代码保护功能,因此如果需要加固应用的安全性,则可以使用诸如:Bitbucket或??GitHub CODEOWNERS??之类的功能。
- 当测试套件跨越多个单独的服务时,人们很难在CI的构建中发现和处理错误。对此,??测试报告??等功能可协助识别和分析问题。
- Monorepo的CI/CD配置可能会出现许多重复的部分。对此,我们可以使用环境变量或参数化管道,来减少样板文件(Boilerplate)。
不要忘了可恢复性
到目前为止,我们只关注了应用的可发布性,下面我们再来关注可恢复性。
版本控制不仅能让我们实现协作、共享知识、跟踪代码、以及管理变更,还提供了在出现问题时的恢复能力。只要我们可以访问到项目中的任何一个变更,便可以“闪回”到任意版本。
不过,由于Multirepos没能记录微服务之间的关系,即:没有任何给定时间点,在生产环境中运行的服务版本的快照,因此,我们若要诊断某些集成类问题,则非常耗时。在某些情况下,我们甚至无法通过回滚微服务来解决问题。
Multirepos在查找失败的根本原因时具有挑战性,有时很难找到“最后一次使用过的微服务配置”
而Monorepo能够轻松地捕获系统的完整快照,以便为我们提供项目的历史记录中任意点所需的所有细节,进而在出现问题时,找到合适的回撤点。
Monorepo具有返回项目历史中任何时间点所需的微服务关系的详细信息
小结
综上所述,到底是应该采取为一个微服务配置一个管道和一个存储库,还是配置一个全局管道和一个共享村库,目前尚无绝对的定论。如果您的微服务是松耦合的话,那么Multirepo和Monorepo都可以正常工作。当然,Multirepos的负载虽大,但可以为您提供更多的自主权。而如果您的服务存在着耦合关系,那么您最好使用Monorepo来保证其可恢复性。
在上文提到的Semaphore平台中,持续的微部署方式能够达到较好的效果。但是在Semaphore On-Premise中,我建议您将核心的微服务迁移到Monorepo处。?
译者介绍
陈峻?(Julian Chen),51CTO社区编辑,具有十多年的IT项目实施经验,善于对内外部资源与风险实施管控,专注传播网络与信息安全知识与经验。
原文标题:??Release Management for Microservices: Multi vs. Monorepos???,作者:Tomas Fernandez?