微服务设计模式 - 快速指南



微服务设计模式 - 概述

微服务是一种基于服务的应用程序开发方法。在这种方法中,大型应用程序将被分解成最小的独立服务单元。微服务是通过将整个应用程序划分为相互连接的服务集合来实现面向服务架构 (SOA) 的过程,其中每个服务只满足一个业务需求。

微服务的概念

在面向服务架构中,整个软件包将被细分为小型、相互连接的业务单元。这些小型业务单元将使用不同的协议相互通信,从而为客户端提供成功的业务。现在问题是,微服务架构 (MSA) 与 SOA 有何不同?简单来说,SOA 是一种设计模式,而微服务是实现 SOA 的一种实现方法,或者可以说微服务是一种 SOA。

以下是我们在开发面向微服务的应用程序时需要记住的一些规则。

  • 独立性 - 每个微服务都应该是独立部署的。

  • 耦合性 - 所有微服务都应该松散耦合,这样一来,一个微服务的更改不会影响其他微服务。

  • 业务目标 - 整个应用程序的每个服务单元都应该是最小的,并且能够实现一个特定的业务目标。

为了应用这些原则,必须处理某些挑战和问题。微服务设计模式讨论了这些常见问题,并提供了相应的解决方案。在接下来的部分中,我们将讨论问题以及使用适用的设计模式的解决方案。

与微服务相关的设计模式分为五大类。

  • 分解设计模式 - 将应用程序分解成更小的微服务。分解设计模式提供了如何以逻辑方式进行分解的见解。

  • 集成设计模式 - 集成设计模式处理应用程序的整体行为。例如,如何在一个调用中获取多个服务的多个结果等。

  • 数据库设计模式 - 数据库设计模式处理如何为微服务定义数据库架构,例如每个服务是否应该拥有一个单独的数据库或使用共享数据库等等。

  • 可观察性设计模式 - 可观察性设计模式考虑日志记录、性能指标等的跟踪。

  • 横切关注点设计模式 - 横切关注点设计模式处理服务发现、外部配置、部署方案等。

按业务能力分解

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,以实现持续交付/部署。当使用微服务架构构建大型复杂应用程序时,主要问题是如何设计松散耦合的微服务,或者如何将大型应用程序分解成小型松散耦合的服务?

解决方案

我们可以为特定的业务能力定义一个微服务。业务能力是指旨在创造价值的业务活动。业务能力可以被称为业务对象。例如:

  • 订单管理 - 订单管理业务能力指的是订单。

  • 客户管理 - 客户管理业务能力指的是客户。

业务能力可以进一步细分为多层层次结构。例如,订单管理可以将交付、库存、服务等作为业务能力。

示例

考虑一个在线书店的例子。它可以具有以下业务能力和相应的微服务:

  • 图书目录管理

  • 库存管理

  • 订单管理

  • 保修管理

Decompose By Business Capability Design Pattern

优点

  • 稳定的架构 - 由于业务能力是稳定的,因此这种架构非常稳定。

  • 跨职能团队 - 开发团队独立工作,是跨职能的,并且围绕功能特性而不是技术特性进行组织。

  • 松散耦合的服务 - 开发的服务将是松散耦合且具有内聚性的。

缺点

  • 需要很好地理解业务 - 需要在理解业务之后识别业务能力。理解组织结构会有所帮助,因为组织是基于其能力构建的。

  • 需要高级别的领域模型 - 需要业务领域对象,因为它们对应于业务能力。

按子域分解

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,以实现持续交付/部署。当使用微服务架构构建大型复杂应用程序时,主要问题是如何设计松散耦合的微服务,或者如何将大型应用程序分解成小型松散耦合的服务?

解决方案

我们可以根据领域驱动设计 (DDD) 子域定义微服务。DDD 将业务视为一个领域,一个领域可以有多个子域。现在每个子域都指不同的领域。例如:

  • 订单管理 - 订单管理子域指的是订单。

  • 客户管理 - 客户管理子域指的是客户。

子域可以使用以下标准进一步分类:

  • 核心域 - 最重要且是应用程序的关键差异化因素。

  • 支撑域 - 与业务相关,用于支持业务活动。

  • 通用域 - 不特定于业务,但用于增强业务运营。

示例

考虑一个在线书店的例子。它可以具有以下子域和相应的微服务:

  • 图书目录管理

  • 库存管理

  • 订单管理

  • 保修管理

Decompose By Subdomain Design Pattern

优点

  • 稳定的架构 - 由于业务子域是稳定的,因此这种架构非常稳定。

  • 跨职能团队 - 开发团队独立工作,是跨职能的,并且围绕功能特性而不是技术特性进行组织。

  • 松散耦合的服务 - 开发的服务将是松散耦合且具有内聚性的。

缺点

  • 需要很好地理解业务 - 需要在理解业务之后识别业务子域。理解组织结构会有所帮助,因为组织是基于其能力构建的。

  • 需要高级别的领域模型 - 需要业务领域对象,因为它们对应于业务子域。

按绞杀者模式分解

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,以实现持续交付/部署。当使用微服务架构构建大型复杂应用程序时,主要问题是如何设计松散耦合的微服务,或者如何将大型应用程序分解成小型松散耦合的服务?

解决方案

我们可以使用绞杀者模式定义微服务。绞杀者应用程序有两种服务:

  • 现有行为 - 这些服务表现出先前存在于单体应用程序中的行为。

  • 新功能 - 这些服务实现新的行为。

因此,随着时间的推移,微服务会增加,而单体应用程序会随着功能从单体应用程序转移到绞杀者应用程序而缩小。

示例

考虑一个在线书店的例子。最初,我们只开发了图书目录管理服务,而其他服务由遗留的单体应用程序支持。在开发过程中,越来越多的服务被开发出来,并且功能从单体应用程序中移走。

Decompose By Strangler Design Pattern

因此,当开发新服务时,单体应用程序会被绞杀,旧组件会被停用,新的微服务会被部署并支持新功能。绞杀者模式可以通过三个步骤实现:

  • 转换 - 独立开发微服务以实现单体应用程序的特定功能。

  • 共存 - 单体应用程序和微服务都将工作。用户可以从两个组件访问功能。

  • 消除 - 一旦新开发的功能准备就绪,就从单体应用程序中移除该功能。

优点

  • 测试驱动开发 - 由于服务是分块开发的,我们可以使用 TDD 进行业务逻辑并确保代码质量。

  • 独立团队 - 团队可以并行地在单体应用程序和微服务上工作,从而形成强大的交付机制。

微服务设计模式 - API 网关

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,以实现持续交付/部署。当使用微服务架构构建大型复杂应用程序时,微服务可以使用不同的协议。例如,一些微服务使用 REST,而另一些微服务遵循 AMQP。现在问题是如何允许客户端无缝地访问每个微服务,而无需担心协议和其他复杂性。

解决方案

我们可以定义一个 API 网关,它将充当所有类型客户端的单一入口点。以下是 API 网关的其他好处:

  • 简单的代理 - API 网关可以充当某些请求的简单代理,将它们重定向到相关服务。

  • 多个服务 - API 网关可以将调用重定向到多个服务。

  • 客户端特定的 API - API 网关还可以提供客户端特定的 API,例如,桌面版与移动应用程序的 API 不同。

  • 协议处理 - API 网关在内部处理每个服务调用的通信协议,客户端只需关注请求/响应。

  • 安全性和身份验证 - API 网关可以实现一种安全机制,只有在身份验证和授权后,每个请求才能到达服务。

示例

考虑一个在线书店的例子。API 网关允许在多个设备上无缝地使用在线书店 API。

API Gateway Design Pattern

优点

  • 客户端隔离 - 客户端无需了解微服务的位置或如何调用它们。

  • 多个服务调用 - API 网关可以处理多个服务并给出一个结果,从而可以减少往返次数并提高性能。

  • 标准接口 - API 网关为客户端提供标准接口以从微服务获取响应。

微服务设计模式 - 聚合器

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,从而实现持续交付/部署。当使用微服务架构构建大型复杂应用程序时,我们经常需要获取多个微服务的组合结果并在应用程序上显示。

解决方案

我们可以定义一个聚合器 (Aggregator) 作为简单的 Web 模块,它充当负载均衡器,这意味着它将根据需求调用不同的服务。下图显示了一个带有聚合器设计的简单微服务 Web 应用程序。如下图所示,“聚合器”负责逐一调用不同的服务。如果我们需要对服务 A、B 和 C 的结果应用任何业务逻辑,那么我们可以在聚合器本身中实现业务逻辑。

Aggregator Pattern

聚合器可以再次作为另一个服务暴露给外部世界,并在需要时被其他人使用。在开发聚合器模式 Web 服务时,我们需要记住我们的每个服务 A、B 和 C 都应该有自己的缓存层,并且应该是全栈式的。

微服务设计模式 - 代理 (Proxy)

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,从而实现持续交付/部署。当使用微服务架构构建大型复杂应用程序时,我们经常需要准备一个统一的接口,可以在每次服务调用之前执行诸如身份验证和授权之类的公共工作。

解决方案

代理微服务模式是聚合器模型的一种变体。在这个模型中,我们将使用代理模块而不是聚合模块。代理服务可以分别调用不同的服务。

Proxy Pattern

在代理模式中,我们可以通过提供一个哑代理层来构建一层额外的安全性。此层的作用类似于接口。

优点

  • 代理模式提供了一个统一的接口,而不是每个微服务不同的接口。

  • 代理模式允许在一个地方应用统一的关注点,例如日志记录、安全等。

客户端 UI 组合

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,从而实现持续交付/部署。现在如何开发一个可以显示来自多个服务数据的 UI 页面/屏幕?

解决方案

每个 UI 团队可以开发一个客户端 UI 组件,例如 Angular 组件,它实现或对应于特定的微服务。对于多个服务,UI 团队负责通过构建由多个特定服务 UI 组件组成的页面来准备骨架 UI 或页面骨架。

Client Side UI Composition Design Pattern

优点

  • 独立的 UI 团队 - 一旦微服务契约可用,每个 UI 团队都可以工作,而无需所有微服务的可用性。

  • 可管理的 UI 开发 - 以组件形式开发的 UI 变得更易于管理和高效。

  • 更轻松的开发 - UI 开发变得更容易和更易于维护。

责任链 (Chain of Responsibilities)

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,从而实现持续交付/部署。如果一个服务需要另一个服务的输出作为依赖项,那么如何处理这种情况?

解决方案

我们可以使用责任链模式。顾名思义,这种组合模式将遵循链式结构。在这里,我们不会在客户端和服务层之间使用任何东西。相反,我们将允许客户端直接与服务通信,并且所有服务都将以一种方式链接起来,即一个服务的输出将成为下一个服务的输入。下图显示了一个典型的链式模式微服务。

Chain of Responsibilities Design Pattern

缺点

这种架构的一个主要缺点是,客户端将被阻塞,直到整个过程完成。因此,强烈建议将链的长度保持尽可能短。

微服务设计模式 - 分支 (Branch)

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,从而实现持续交付/部署。现在考虑一种情况,一个服务需要另一个服务的输出作为依赖项,并且客户端可以调用任何服务。

解决方案

我们在这里可以使用分支微服务设计模式。分支微服务模式是聚合器模式和链式模式的扩展版本。在这个设计模式中,客户端可以直接与服务通信。此外,一个服务可以同时与多个服务通信。下图是分支微服务的示意图。

Branch Microservices Design Pattern

优点

分支微服务模式允许开发人员动态配置服务调用。所有服务调用都将并发发生,这意味着服务 A 可以同时调用服务 B 和 C。

每个服务一个数据库

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,从而实现持续交付/部署。基于微服务的应用程序中数据库的结构/架构应该是什么?

解决方案

我们可以将每个微服务的数据保持为该微服务的私有数据,并且这些数据只能通过相关的微服务访问。微服务将使用自己的数据库进行事务处理。下图显示了每个服务设计模式的数据库实现。

Database per Service Microservices Design Pattern

每个服务一个数据库并不总是需要单独配置数据库。考虑到关系数据库,我们可以通过以下方式实现该模式。

  • 每个服务的私有表 - 每个微服务都可以利用一组表,并且这些表只能通过其相关的微服务访问。

  • 每个服务的模式 - 可以为每个微服务定义一个单独的模式。

  • 每个服务的数据库服务器 - 可以为每个微服务配置整个数据库服务器。

服务共享数据库

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,从而实现持续交付/部署。基于微服务的应用程序中数据库的结构/架构应该是什么?

解决方案

我们可以使用一个在微服务之间共享的数据库。每个服务都可以自由地使用其他服务可以访问的数据。数据库将维护 ACID 事务。

Shared Database per Service Microservices Design Pattern

在这个模式中,每个服务都应该使用底层数据库的事务管理,以便可以利用数据库的 ACID 属性。考虑以下伪代码:

BEGIN TRANSACTION
…
SELECT * FROM ORDERS WHERE CUSTOMER_ID = ?
…
SELECT CREDIT_LIMIT FROM CUSTOMERS WHERE CUSTOMER_ID = ?
…
INSERT INTO ORDERS ... WHERE ORDER_LIMIT < CREDIT_LIMIT
…
COMMIT TRANSACTION

这里订单服务使用数据库事务来确保在订购期间检查客户的信用额度。

命令查询责任隔离 (CQRS)

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,从而实现持续交付/部署;如果我们使用了每个服务一个数据库的设计模式,那么如何进行需要来自多个服务的数据的查询?

解决方案

我们可以定义一个视图数据库,这是一个只读数据,用于支持所需的查询。应用程序将通过订阅拥有数据服务的事件来保持视图数据库的最新状态。在这个设计模式中,我们将更新和读取操作分开。一个服务只读取数据,其他服务更新数据。

Command Query Responsibility Segregator Pattern

为了实现这个模式,我们经常需要重构领域模型以支持查询数据和更新数据的单独操作,以便每个操作都可以由微服务独立处理。CQRS 模式确保读取数据的操作与更新数据的操作分开。因此,一个操作可以读取或写入数据,但不能同时执行两者。

现在多个服务可以更新记录并将事件发送到应用程序以更新视图数据库。这有助于查询服务获取一致的数据,而不会影响性能。

微服务设计模式 - Saga

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,从而实现持续交付/部署;如果我们使用了每个服务一个数据库的设计模式,那么如何实现跨越多个服务的事务?

解决方案

我们可以使用 Saga 模式。Saga 是一系列本地事务。在这个模式中,每个事务都会更新数据库并触发事件或发布消息以进行 Saga 中的下一个事务。如果任何本地事务失败,Saga 将触发一系列事务来撤消本地事务迄今为止所做的更改。

考虑订单服务和客户服务的示例。订单服务可以下订单,然后询问客户服务是否超过信用额度。如果信用额度超过,客户服务将向订单服务发出事件以取消订单,否则成功下单。

Saga Pattern

为了实现这个模式,我们经常需要基于编排的 Saga 或基于协调器的 Saga。

在基于编排的 Saga 中,服务在本地事务期间处理领域事件,并完成事务或撤消事务;而在基于协调器的 Saga 中,协调器对象在本地事务期间处理事件,然后告诉协调器要执行哪个本地事务。

异步消息 (Asynchronous Messaging)

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,从而实现持续交付/部署。微服务处理来自客户端的请求,并且经常需要与其他微服务通信以完成请求。因此需要进程间通信协议。

解决方案

我们可以使用异步消息模式进行服务间通信,因为使用同步通信会导致服务的紧密耦合,并且还要求客户端和服务在请求期间都可用。

使用异步消息,服务可以通过在消息通道上交换消息来通信。以下是异步消息通信的一些不同方法。

  • 请求/同步响应 - 在此方法中,服务向另一个服务发出请求并立即期望回复。

  • 通知 - 在此方法中,服务向接收者发送消息,但不期望任何响应。接收者也不期望发送响应。

  • 请求/异步响应 - 在此方法中,服务向另一个服务发出请求,并期望在合理的时间范围内收到回复。

  • 发布/订阅 - 在此方法中,服务向零个或多个接收者发布消息。订阅该消息的服务将收到相同的回复。不需要响应。

  • 发布/异步响应 - 在此方法中,服务向零个或多个接收者发布消息。订阅该消息的服务将收到相同的回复。其中一些会发送确认/回复。

示例

RabbitMQ 和 Apache Kafka 是微服务领域异步消息传递的良好示例。

事件溯源

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,从而实现持续交付/部署;如果我们使用了每个服务一个数据库的设计模式,那么如何实现跨越多个服务的事务?

解决方案

我们可以使用事件溯源模式进行服务间通信。在这种类型的通信中,每个服务都会为每次执行的操作将事件持久化到事件存储中。每个服务都可以订阅这些事件并相应地更新其事务状态。考虑订单服务与客户服务的案例。客户服务可以订阅订单服务更新的事件并相应地更新其状态。

Event Sourcing Pattern

优点

以下是使用事件溯源模式的优点:

  • 非常适合事件驱动的架构 - 此模式允许在状态更改时可靠地发布事件。

  • 持久化事件 - 由于持久化的是事件而不是领域对象,因此不会出现对象关系不匹配的情况。

  • 审计日志 - 由于每个更改都会捕获事件,因此审计日志涵盖了 100% 的更改。

  • 实体状态标识 - 我们可以在事件数据库上创建时间查询,以检查实体在任何时间点的当前状态。

  • 单体到微服务架构的迁移变得更容易 - 使用事件溯源模式,我们可以创建通过事件进行通信的松散耦合的微服务。因此,从单体到基于微服务的应用程序开发的迁移变得更容易。

日志聚合

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,从而实现持续交付/部署。请求通常跨越多个服务。每个服务实例都以标准化格式在其日志文件中写入一些信息。这些日志可以是信息、错误、警告或调试日志。如何使用这些日志分析和排除应用程序问题?

解决方案

我们可以使用集中的日志服务,它聚合来自每个服务的日志。用户应该能够搜索和分析此日志服务提供的日志。用户应该能够在日志中出现特定类型的消息时配置警报。

关联 ID

当第一个微服务接收到调用时,它应该生成一个关联 ID,然后可以将其传递给下游服务。此关联 ID 应该记录在所有微服务中。这将有助于跟踪跨越多个服务的相关信息。

可搜索的日志

由于日志应放置在集中位置,因此下图展示了如何使用 Kafka、LogStash 和 Kibana 来聚合日志并使用所需的过滤器搜索已索引的日志。

Log Aggregation Pattern

微服务生成日志,这些日志使用 kafka 日志追加器发布,然后将日志消息输出到 kafka 集群。LogStash 从 kafka 中提取消息,转换消息并发布到 Elasticsearch 容器。现在,Kibana 提供了一个可视化界面来搜索/读取 Elasticsearch 容器中已索引的日志,并提供所需的过滤器。

性能指标

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,以实现持续交付/部署。如何分析和解决应用程序问题?如何跟踪应用程序性能并检查瓶颈?如何以最少的运行时开销跟踪多个服务?

解决方案

我们可以实现一个监控服务,负责收集有关各个操作的统计数据,以及一个中央指标服务,该服务应聚合指标并提供报告和警报。这些服务可以通过两种方式收集性能指标:

  • 推送 - 服务将指标推送到中央指标服务。

  • 拉取 - 中央指标服务从服务中拉取指标。

示例

以下是监控库的示例:

以下是指标聚合库的示例:

  • Prometheus - 一个开源系统监控和警报工具包。

  • AWS CloudWatch - AWS 资源和服务可观察性和监控服务。

分布式追踪

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,以实现持续交付/部署。请求通常跨越多个服务。使用外部监控,我们可以检查整体响应时间和调用次数,但是如何深入了解单个事务/操作?服务可以使用数据库、消息队列、事件溯源等。如何跟踪跨越多个服务的散布日志?

解决方案

我们可以监控一个设计用于执行以下操作的服务:

  • 关联 ID - 为每个外部请求生成唯一的外部请求 ID,并将此外部 ID 传递给处理请求的每个服务。

  • 记录关联 ID - 处理服务生成的每个日志消息都应具有此关联 ID。

  • 记录详细信息 - 当服务处理请求时,在日志中记录开始/结束时间和其他相关详细信息。

可搜索的日志

由于日志应放置在集中位置,因此下图展示了如何使用 Kafka、LogStash 和 Kibana 来聚合日志并使用所需的过滤器搜索已索引的日志。

Log Aggregator Pattern

微服务生成日志,这些日志使用 kafka 日志追加器发布,然后将日志消息输出到 kafka 集群。LogStash 从 kafka 中提取消息,转换消息并发布到 Elasticsearch 容器。现在,Kibana 提供了一个可视化界面来搜索/读取 Elasticsearch 容器中已索引的日志,并提供所需的过滤器。

微服务设计模式 - 健康检查

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,以实现持续交付/部署。现在,如果数据库宕机或无法承受更多连接,则监控系统应发出警报。负载均衡器/服务注册表/API 网关不应将任何请求重定向到此类失败的服务实例。因此,我们需要检测正在运行的服务实例是否能够接收请求。

解决方案

我们可以为每个服务添加一个健康检查点,例如 HTTP /health,它返回服务健康状态。此端点可以执行以下任务来检查服务健康状况:

  • 连接可用性 - 当前服务使用的数据库连接或基础设施服务的连接状态。

  • 主机状态 - 主机的状态,例如磁盘空间、CPU 使用率、内存使用率等。

  • 特定于应用程序的逻辑 - 确定服务可用性的业务逻辑。

现在,监控服务(例如负载均衡器、服务注册表)定期调用健康检查端点以检查服务实例的健康状况。

外部配置

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,以实现持续交付/部署。这些服务通常与基础设施服务或第三方服务交互。

基础设施服务可能包括服务注册表、消息代理、数据库服务器。第三方服务可以是支付服务、电子邮件服务、消息服务。除了不同的服务之外,环境也经常不同。考虑以下情况:

  • 配置数据 - 应向微服务提供外部/第三方服务的配置,例如数据库凭据、网络 URL 等。

  • 多个环境 - 通常存在不同的环境,例如开发、测试、预发布或预生产和生产环境。服务应部署在每个环境中,而无需任何代码修改。

  • 不同的配置数据 - 外部/第三方服务的配置从开发到生产环境也会有所不同,例如开发数据库到生产数据库、测试支付处理器与原始支付处理器服务。

解决方案

我们可以将所有配置从数据库凭据到网络 URL 外部化。服务将在启动时读取配置数据,例如从属性文件/系统环境变量或使用命令行参数。此模式有助于部署微服务,无需任何修改/重新编译。

服务发现

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,以实现持续交付/部署。这些服务通常在容器化/虚拟环境中运行,它们的实例数量和位置会动态变化。

因此,我们需要一种机制来使微服务的客户端能够向动态变化的服务实例发出请求。

解决方案

我们可以使用服务发现模式。要实现此模式,我们需要在特定固定位置运行路由器/负载均衡器,以及所有微服务实例都注册的服务注册表。

现在,客户端发出服务请求,它将到达负载均衡器,然后负载均衡器查询服务注册表。如果服务实例可用,则请求将重定向到可用的服务实例。

Service Discovery Pattern

微服务设计模式 - 断路器

问题陈述

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都可以以敏捷的方式独立开发,以实现持续交付/部署。这些服务经常与其他微服务交互。现在,服务超载或不可用的可能性始终存在。在这种情况下,调用服务也将等待。如果多个服务被阻塞,则会影响性能,并可能对整个应用程序产生级联影响。

现在,如何防止服务故障或网络故障级联到其他服务?如果一项服务宕机,则不应向其发出更多请求。

解决方案

我们可以使用断路器模式,其中代理服务充当断路器。每个服务都应通过代理服务调用。代理服务维护超时和故障计数。如果连续故障超过阈值故障计数,则代理服务将跳闸断路器并启动超时时间段。在此超时时间段内,所有请求都将失败。一旦此超时时间段结束,代理服务允许一定数量的测试请求传递到提供者服务。如果请求成功,代理服务将恢复操作;否则,它将再次跳闸断路器并启动超时时间段,在此期间将不接受任何请求。

蓝绿部署

微服务架构将应用程序构建为一组松散耦合的微服务,每个服务都应以敏捷的方式独立开发,以实现持续交付/部署。当要使用微服务架构构建大型复杂应用程序时,主要问题是如何设计松散耦合的微服务,或者如何在保持系统处于生产状态的同时,将大型应用程序分解成小型松散耦合的服务。

解决方案

我们可以使用蓝绿部署来定义部署新开发的微服务。在此模型中,用户流量会逐渐从旧应用程序转移到新的微服务应用程序。一旦微服务在生产环境中可用,负载均衡器就会将针对旧应用程序的请求重定向到新的微服务。

  • 蓝色环境 - 在生产环境中运行的旧应用程序称为蓝色环境。

  • 绿色环境 - 部署的新服务复制了旧应用程序的给定部分,称为绿色环境。

因此,随着时间的推移,微服务会增加,而整体应用会随着功能从整体应用迁移到微服务应用程序而缩小。

示例

考虑一个在线书店的例子。最初,我们只开发了图书目录管理服务,其他服务由遗留整体式应用程序支持。在开发过程中,越来越多的服务被开发出来,并且功能从整体应用中移出。

Blue Green Deployment Design Pattern

这种部署模式有助于减少停机时间,甚至在从整体式应用程序迁移到基于微服务的应用程序时实现零停机时间。

广告