eShopOnContainers分析
eShopOnContainers 一个基于微服务的 .NET Core示例应用程序。
.NET Core 参考应用程序,由 Microsoft 提供支持,基于简化的微服务架构和 Docker 容器。
该架构提出了一种面向微服务的架构实现,具有多个自治微服务(每个拥有自己的数据/数据库)并在每个微服务中实现不同的方法
eShopOnContainers
服务自治
每项微服务(身份、目录、订购、购物篮、营销、位置)都是自主的。它拥有自己的数据(存储),并且不依赖于任何其他服务。为了与其他服务通信,它通过 RabbitMQ 或 Azure 服务总线的事件总线上的发布/订阅者使用事件驱动模型。每个服务都包含自己的 HTTP API,提供检索数据和执行特定操作等功能。例如,Ordering 服务包含一个 API 项目,该项目具有用于检索订单和取消订单的 HTTP 资源。
该架构提出了一种面向微服务的架构实现,具有多个自治微服务(每个微服务拥有自己的数据/数据库)。微服务还展示了从简单的 CRUD 到更精细的 DDD/CQRS 模式的不同方法。HTTP 是客户端应用程序和微服务之间的通信协议,以及微服务之间基于异步消息的通信。可以使用 RabbitMQ 或 Azure 服务总线处理消息队列,以传达集成事件。
领域事件在排序微服务中通过使用MediatR进行处理,MediatR是一个简单的进程内实现 Mediator 模式。
查看作文
由于每个服务都提供了自己的 HTTP API 来检索该服务中拥有的特定数据,因此您最终需要从多个服务中组合视图。Backend-For-Frontends (BFF) 模式用于为特定客户端类型提供单个 API 后端。例如,MVC 和 SPA 应用使用 Web-Shipping 和 Web-Marketing BFF,而 Xamarin 移动应用使用 Mobile-Shopping 和 Mobile-Marketing BFF。最终,这些 BFF 对所需服务进行 HTTP 调用,以组成客户端所需的数据。
事件总线
eShopOnContainers 包括一个简化的 EventBus 抽象来处理集成事件,以及两个实现,一个基于RabbitMQ,另一个基于Azure Service Bus。
对于生产级解决方案,您应该使用基于强大产品(例如NServiceBus )的更强大的实现。您甚至可以在此处看到带有 NServiceBus 的 eShopOnContainers 的(有些过时的)实现:https ://github.com/Particular/eShopOnContainers 。
在微服务(集成事件)之间实现基于事件的通信
通过事件总线发布了 PriceUpdated 事件,因此价格更新传播到购物篮和其他微服务。
如果需要高级别抽象和更丰富的功能(如 Sagas),用于简化分布式开发的长时间运行进程,则可评估 NServiceBus、MassTransit 和 Brighter 等其他商用和开源服务总线。
事件总线可实现发布/订阅式通信,无需组件之间相互显式识别,如图 6-19 所示。
图 6-19。 事件总线的发布/订阅基础知识
上图显示了微服务 A 发布到事件总线,这会分发到订阅微服务 B 和 C,发布服务器无需知道订阅服务器。 事件总线与观察者模式和发布-订阅模式相关。
在图 6-20 中,可看到事件总线的抽象,包含基于 RabbitMQ、Azure 服务总线或其他事件/消息中转站等基础结构消息技术的多个实现。
事件总线的多个实现
最好通过接口定义事件总线,以便它可使用多种技术(例如 RabbitMQ、Azure 服务总线等)来实现。 但是,如前所述,仅当需要由你的抽象支持的基本事件总线功能时,才适合使用你自己的抽象(事件总线接口)。 如果需要更丰富的服务总线功能,应使用你喜欢的商用服务总线提供的 API 和抽象,而不是你自己的抽象。
RabbitMQ 的事件总线实现,微服务可订阅事件、发布事件和接收事件
RabbitMQ 充当消息发布服务器和订阅者之间的中介,处理分发。
gRPC
大多数微服务之间的通信都是使用 EventBus 和“发布/订阅”模式解耦的。
但是,自定义聚合器和内部微服务之间的通信目前是使用 gRPC 实现的,而不是 HTTP/JSON。gRPC 是一种基于 RPC 的协议,具有出色的性能和低带宽使用率,使其成为内部微服务通信的最佳候选者。
有关 gRPC 和 eShopOnContainers 的更多信息,请参阅此 wiki 中的 gRPC 文章
eShopOnContainers 利用 gRPC 进行内部微服务到微服务的同步通信。请注意,在 eShop 中,微服务之间的大部分通信都是使用事件总线(支持 RabbitMQ 或 Azure 服务总线)进行解耦和异步的。
gRPC 是一种基于 HTTP/2 和协议缓冲区的高性能通信协议。它应该是服务之间直接同步通信的主要选择(与用于异步通信(如队列或发布/订阅)的 AMQP 等其他协议相反)。
与使用 HTTP 和 JSON 相比,它的主要优点是:
- 协议缓冲区是一种二进制、高性能的序列化机制。根据语言实现,协议缓冲区可以比 JSON 序列化快 8 倍,而消息可以小 60%-80% 左右。
- 支持数据流
- 服务和客户端之间的合同是明确的(通过使用 _proto_ 文件)
在当前的实现中,gRPC 的使用仅限于聚合器和微服务之间的通信。从聚合器到微服务:使用 gRPC
API 网关
该架构还包括 API 网关和前端后端 (BFF)模式的实现,以发布简化的 API,并包括用于隐藏/保护客户端应用程序或外部消费者的内部微服务的额外安全措施。
这些 API 网关是使用Envoy实现的,Envoy是一种 OSS 高性能、生产就绪、代理和 API 网关。目前,这些 API 网关仅将请求转发到内部微服务和自定义聚合器,然后为客户端提供单个基本 URL 的体验。未来可以实现的功能有:
- 从/到 gRPC 到/从 HTTP/REST 的自动转换。
- 认证和授权管理
- 缓存支持
注意以前版本的 eShopOnContainers 使用Ocelot而不是 Envoy。Ocelot 是一个很棒的 .NET Core OSS 开放项目,用于创建 API 网关。Ocelot 支持广泛的功能集,它是每个基于 :NET Core 的项目中的重要候选者。然而,缺乏对 gRPC 的支持是在 eShopOnContainers 中为 Envoy 更改 Ocelot 的主要原因。
内部架构模式
根据其内部架构模式和方法,有不同类型的微服务,具体取决于它们的用途,如下图所示。
数据库服务器
有四个 SQL Server 数据库,但它们都部署到一个容器中,以尽可能降低内存需求。这不是生产部署的推荐方法,您应该使用高可用性解决方案。
还有一个 Redis 和一个 MongoDb 实例,在不同的容器中,作为两个广泛使用的 NO-SQL 数据库的示例。
eShopOnContainers 订购微服务中采用的、使用域驱动设计 (DDD) 方法定义的模式 。 (我们将在下一部分中了解这些 DDD 模式,下一节介绍 eShopOnContainers 订购微服务的实现 。)
底线是每个微服务可基于不同设计模式具有不同内部体系结构。 并非所有微服务都应使用高级 DDD 模式实现,因为这可能会对其过度工程。类似地,具有不断变化业务逻辑的复杂微服务不应作为 CRUD 组件实现,否则会导致低质量代码。
系统架构
Catalog microservice 目录微服务:是由数据驱动的简单服务。此类型的服务在单个 ASP.NET Core Web API 项目中实现其全部功能,该项目包含用于其数据模型、业务逻辑和数据访问代码的类。