其乐融融的IT技术小站

多存储库与单存储库的微服务发布管理比较

译者 | 陈峻

审校 | 孙淑娟

让我们来设想一个由数十个可持续部署(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

赞 ()
分享到:更多 ()

相关推荐

内容页底部广告位3
留言与评论(共有 0 条评论)
   
验证码: