定期发布的微服务架构版本控制

时间:2021-03-30 13:27:51

标签: continuous-integration microservices release versioning continuous-delivery

我正在尝试围绕在基于微服务的架构中定期发布版本控制的最佳实践进行思考。

目前我们的系统被分解成多个不同的存储库:

  • 前端
  • 后端
  • 数据库
  • API 网关
  • Docker-compose-env

这些组件中的每一个都必须独立开发、构建、测试、容器化和部署。但是发布周期是同步的和周期性的。 Docker-compose-env 项目包含启动所有兼容服务版本的环境定义,用于开发和集成测试。

当前的版本控制策略如下:

  1. master 分支的每个提交都标记有语义版本并推送到 docker 注册表(语义标记用于在开发周期中跟踪依赖项)
  2. 每个对持久 release 分支的合并提交都被标记为 release 标签,并推送到 docker 注册表(发布标签用于将项目版本同步到一起以进行季度发布)

master 是主干,从 masterrelease 由 PR 发起定期发布构建。

enter image description here

我怀疑这是否是在定期发布上使用基于微服务的架构来管理版本的最佳方式。感谢您提供任何反馈或提示。

2 个答案:

答案 0 :(得分:2)

<块引用>

这些组件中的每一个都必须独立开发、构建、测试、容器化和部署。但是发布周期是同步和周期性的。

这里有一个矛盾。微服务主要解决组织问题 - 重点是团队应该能够尽可能独立工作。

团队之间的同步使他们变慢。这可以以不同的方式发生,例如等待另一个版本在共享测试环境中部署,或者使用相同的共享数据库架构,或者同时发布。

<块引用>

我怀疑这是否是在定期发布中使用基于微服务的架构管理版本的最佳方式。

尽量避免“同步发布”,而是确保不破坏服务之间的任何合同(例如,不破坏 API 更改)。尝试更频繁地发布,您希望小批量工作以降低部署和更改的风险。尽量不要一堆一堆的变化,持续部署 - 持续交付。

答案 1 :(得分:0)

发布周期同步

我认为您需要同时同步发布所有服务这一事实可能表明您的服务之间的耦合度高于应有的水平,并且您管理它的方式可能可以改进。

问题是你如何设计你的开发团队处理不同的微服务,以便在他们引入变化时不会破坏彼此的微服务?

版本控制和管理变更

有两个方面对它的工作很重要,它们是:

  1. 版本控制以及您如何实施和使用版本控制。
  2. 团队沟通。引入重大变更时团队之间的沟通。

这是什么意思?

首先是关于版本控制。您的微服务正在相互通信。 无论使用 Rest(或 SOAP 或 gRPC 或其他)或消息传递(队列)进行同步或异步通信,他们都需要依赖一些合同。这些契约将是一些 API 契约(就 Java/C# 类/接口而言)。它们需要稳定,因为它们可以被其他微服务使用。

建议:我建议独立于合约的版本控制对微服务进行版本控制。 示例:

  • 微服务 order-micro-service 的最新版本可能是 v1.0.0,而 Contracts order-micro-service-contracts 的版本也可能是 v1.0.0。
  • 微服务客户微服务可能是最新版本 v3.0.0,但合同客户微服务合同可能是版本 v2.2.1。
  • Micro-service product-micro-service 可能是最新的 v3.0.0 版本,Contracts product-micro-service-contracts 可能是 v4.0.0 版本。

从上面的示例中可以看出,来自微服务的版本及其对应的公开合约可以相同,但也可以不同。原因很简单,你可以在不改变合约的情况下对微服务进行更改(一些内部业务逻辑更改)。并且你还可以在不改变微服务逻辑的情况下对合约进行更改。通常,更改会同时发生在两者上。您更新了一些 api 业务逻辑,您可以针对这些逻辑调整公开的合约。但有时微服务逻辑的重大更改不一定是合约的重大更改。如您所见,这为您提供了极大的灵活性。这样做的好处不仅是灵活性,还有一个事实,即微服务 A 将只依赖于微服务 B 的合同,而不是微服务 B 本身。这只是一个建议,您也可以为微服务及其公开的合约使用一个版本。

关于团队沟通。我的意思是,如果您有一个组织,其中有多个团队在系统的不同领域工作,并且每个团队负责来自特定域的一个或多个微服务。

如果您使用语义版本控制,例如 MAJOR.MINOR.PATCH,例如 v1.3.5,那么您可以通过以下方式进行。 有几件事情需要考虑:

  • 合同补丁/小改动 PATCH 或 MINOR 更改版本升级的更改不应该是破坏性更改,并且应该始终向后兼容使用这些合同的消费者。这意味着您应该确保从 1.3.0 版本升级到 1.4.0 对消费者来说不应该是一个问题,无论他是升级到 1.4.0 还是在 1.3.0 上停留更长时间。理想情况下,所有消费者都应该更新到最新版本,但即使他们在一段时间内没有更新,也不会因更改而中断。例如,您将进行此类升级的更改将是添加新的合同模型或使用新的非必填字段更新现有模型,或将接受的字符串长度从字段从 20 增加到 50 或类似。
  • 合同重大或重大变更 通常是一个大的变化,也可以是突破性的变化。如果这是一个突破性的变化,那么我们需要一些团队流程到位。使用这些合同的团队需要被通知更改将提前发生,即使在发布新版本时,也应确保两个版本的合同(旧的和新的)都可以工作的过渡期(或冲刺)。这将为受影响的团队/微服务提供足够的时间来升级和调整他们的服务。之后,可以弃用向后兼容性妥协合同/代码。有时,在某些情况下,重大变更合同变更的解决方案是引入该模型(类)的完整新版本,而不是对同一模型进行硬更改。例如,您可以拥有一个 CustomerModel 类,然后引入 CustomerModelV2 并在一段时间后删除旧的 CustomerModel 类。这是一种常见的情况,您有一个事件(来自队列的消息)的合同模型,例如:CustomerCreated。您可以拥有 CustomerCreated 和 CustomerCreatedV2。您可以在特定时间段内发布这两条消息,直到消费者采用和弃用(停止发布事件并删除合同模型)CustomerCreated 事件。这取决于您的特定业务逻辑或案例。
  • 微服务变化 无论更改只是服务中的错误修复、小更改还是大更改,如果您的版本控制与合同分开,它都不应该影响其他微服务,至少不会影响合同管理预期。对微服务进行版本更新只会让您有可能独立部署它。

微服务独立部署

如果您应用上述建议,您将更接近于您可以独立部署微服务且无需同步部署所有服务的情况。

使用微服务的最大优势之一是能够独立于系统的其他部分部署微服务,因此如果您有机会这样做,您应该去尝试。

<块引用>

这些组件中的每一个都必须经过开发、构建、测试, 容器化和独立部署。但是发布周期是 同步和周期性。

既然你已经独立开发、构建和测试,你也可以独立发布。

我知道所有这些建议的更改不仅是技术上的,而且是组织上的更改,例如团队沟通、团队设置等。但通常在使用微服务处理大型系统时,它会在这两个世界之间做出妥协,并试图为您的组织和业务找到最佳流程和解决方案。