微服务的发布管理


想象一个由数十个持续部署的自治服务组成的微服务应用程序。每个应用程序的服务群都有自己的存储库,具有不同的版本控制方案和不同的团队不断发布新版本。
谜语:我怎样才能知道(整个)应用程序的版本?由于变更历史分散在数十个存储库中,那么跟踪变更的最有效方法是什么?我们如何管理应用程序发布?
任何使用微服务架构的团队,包括我们在 Semaphore 的团队,都必须处理这些问题。在这篇文章中,我想看看几种不同的方法来回答它们。

一种常见的方法:一个微服务,一个存储库
开始使用微服务架构应用程序的最常见方法是使用multirepo方法:

  1. 设计被分解为微服务。
  2. 为每个微服务创建一个单独的存储库(multirepo 中的“multi”来自哪里)。
  3. 每个存储库都有一个独立的CI/CD 管道,用于将微服务持续部署到生产中。

让我们将这种细粒度的持续部署形式称为微部署,因为没有更好的术语。通过微部署,微服务版本可以独立地进行碰撞和部署,几乎不需要集成测试。

微部署是将代码组织成多存储库的副作用。作为参考,这是我们目前为 Semaphore CI/CD 部署微服务的方式。

维护多个微服务版本
对于 Netflix 或 Semaphore CI/CD 等托管应用程序而言,持续微部署是理想的选择,因为用户或客户不知道(或不感兴趣)在幕后运行的单个微服务版本。
然而,对于在本地运行相同应用程序的人来说,情况就大不相同了。在这种情况下,持续部署不起作用。我们回到发布时间表,仅在这种情况下,发布包含固定在特定版本的一组微服务。
当然,私有的 Airbnb 没有意义,但私有的 CI/CD 平台可以。例如,您可以使用Semaphore On-Premise在防火墙后面运行全功能版本的 Semaphore CI/CD 。

发布组织成 multirepos 的应用程序所需的步骤通常如下所示:

  1. 在每个 repo 中,标记将要发布的微服务版本。
  2. 对于每个微服务,构建一个 Docker 镜像并将微服务版本映射到镜像标签。
  3. 在单独的测试环境中测试发布候选。这通常涉及集成测试、验收测试,也许还有一些手动测试。
  4. 在更新文档之前,检查每个存储库并为发布更改日志编译更改列表。
  5. 确定旧版本所需的修补程序。
  6. 发布版本。

考虑到一个应用程序可以包含数十个微服务(和存储库),很容易看出以这种方式发布会导致大量重复的管理开销。

使用 monorepos 管理微服务版本
正如我们所见,multirepos 更适合持续部署,而不是定期、非持续发布。那么,让我们看看光谱的另一端会发生什么;当我们将所有微服务收集到一个共享存储库中时。这就是谷歌、Airbnb 和 Uber 等公司多年来一直使用的 monorepo 方法。

monorepo 策略让微服务感觉更像是一个单体,但以一种很好的方式:

  • 创建发布就像创建分支和使用标签一样简单。
  • 单个 CI/CD 流程可标准化测试和部署。
  • 集成和验收测试更容易实现。
  • 单个 Git 历史记录更易于理解,简化了编写变更日志和更新文档的过程。


与往常一样,改变范式涉及一些权衡:
  • 因为所有更改都提交在一个地方,所以 CI 服务器承受着更大的压力。我们可以通过使用基于更改的执行或像BazelPants这样的 monorepo 感知工具来处理这个问题。
  • Git 没有内置的代码保护功能。因此,如果信任是一个因素,我们应该使用像 Bitbucket 或 GitHub CODEOWNERS这样的功能。
  • 当测试套件跨越许多单独的服务时,在 CI 构建中发现错误会让人感到不知所措。测试报告等功能可以帮助您一目了然地识别和分析问题。
  • monorepo CI/CD 配置可能有很多重复的部分。我们可以使用环境变量或参数化管道来减少样板文件。

永远不要离安全太远
到目前为止,我们只关注应用程序的可发布性,但还有另一个因素可能会给 monorepos 带来优势。
版本控制不仅允许我们协作、共享知识、跟踪代码和管理更改,它还提供了在出现问题时恢复的能力。只要我们可以访问项目中的每一个更改,我们就可以随时返回。
然而,Multirepos 无法提供完整的图片。没有记录微服务之间的关系,即没有任何给定时间在生产中运行的各个服务版本的快照。因此,诊断集成问题可能非常耗时,并且在某些情况下,通过回滚微服务来解决问题是不可能的。

Monorepos 不受此影响。monorepo 捕获系统的完整快照。我们拥有返回项目历史中任何一点所需的所有细节。因此,当出现问题时,我们总能找到合适的地方撤退。

总结
每个微服务一个管道和一个仓库?还是一个共享仓库和一个全球管道?没有适合所有情况的单一最佳答案。如果您的微服务是松耦合的,那么 multirepo 或 monorepo 都可以正常工作。Multirepos 需要更多的工作,但提供更多的自主权。但是,如果您的服务有些耦合,最好使用 monorepo 来明确这种关系。因此,当您有疑问时,只要您能够接受权衡,monorepo 可能是一个更安全的选择。
在 Semaphore 中,持续的微部署对我们来说效果很好,但 Semaphore On-Premise 迫使我们进行调整。虽然最终解决方案仍有争议,但几乎可以肯定的是,它将涉及将核心微服务迁移到 monorepo。