《微服务架构设计模式》读书笔记 | 第5章 微服务架构中的业务逻辑设计

本文主要是介绍《微服务架构设计模式》读书笔记 | 第5章 微服务架构中的业务逻辑设计,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

第5章 微服务架构中的业务逻辑设计

  • 前言
  • 1. 业务逻辑组织模式
    • 1.1 一个典型的服务架构
    • 1.2 使用事务脚本模式设计业务逻辑
    • 1.3 使用领域模型模式设计业务逻辑
    • 1.4 关于领域驱动设计
  • 2. 使用聚合模式设计领域模型
    • 2.1 聚合拥有明确的边界
    • 2.2 聚合规则
    • 2.3 聚合的颗粒度
    • 2.4 使用聚合设计业务
    • 2.5 Order Service基于聚合设计的业务逻辑
  • 3. 发布领域事件
    • 3.1 领域事件的应用场景
    • 3.2 领域事件的特点
    • 3.3 事件增强
    • 3.4 识别领域事件
    • 3.5 生成领域事件
    • 3.6 发布领域事件
    • 3.7 消费领域事件
  • 4. Kichen Service的业务逻辑
    • 4.1 Kichen Service的设计
    • 4.2 Ticket类的结构
    • 4.3 Ticket聚合的行为
    • 4.4 KitchenService的领域服务
    • 4.5 KitchenServiceCommandHandler类
  • 5. Order Service的业务逻辑
    • 5.1 Order Service的设计
    • 5.2 Order聚合的结构
    • 5.3 Order聚合状态机
    • 5.4 OrderService类
  • 6. 微服务与单体应用程序的业务逻辑异同点
  • 7. 本章小结
  • 最后


前言

这是一本关于微服务架构设计方面的书,这是本人阅读的学习笔记。首先对一些符号做些说明:

()为补充,一般是书本里的内容;
[]符号为笔者笔注;


1. 业务逻辑组织模式

组织业务逻辑有两种主要的模式:面向过程的事务脚本模式和面向对象的领域建模模式。

1.1 一个典型的服务架构

业务逻辑周围是入站和出站适配器。

  • 入站适配器:处理来自客户端的请求并调用业务逻辑;
  • 出站适配器:被业务逻辑调用,然后它们再调用其他服务和外部程序应用;

Order Service具有六边形架构

Order Service具有六边形架构
此服务由业务逻辑和以下适配器组成:

  • REST API adapter:入站适配器,实现REST API,这些API会调用业务逻辑;
  • OrderCommandHandlers:入站适配器,它接受来自消息代理的出站适配器,并调用业务逻辑;
  • Database Adapter:由业务逻辑调用以访问数据库的出站适配器;
  • Domain Event Publishing Adapter:将事件发布到消息代理的出站适配器;

1.2 使用事务脚本模式设计业务逻辑

事务脚本:将业务逻辑组织为面向过程的事务脚本的集合,每种类型的请求都有一个脚本。

使用事务脚本模式设计业务逻辑
特点

  • 实现行为的类与存储状态的类是分开的;
  • 脚本通常在服务类中;
  • 每个服务都有一个用于请求或系统操作的方法;这个方法实现请求的业务逻辑;

1.3 使用领域模型模式设计业务逻辑

领域模型:将业务逻辑组织为由具有状态和行为的类构成的对象模型。

使用领域模型模式设计业务逻辑
特点

  • 服务方法通常很简单(因为服务方法几乎总是调用持久化领域对象,这些对象中包含大量业务逻辑);
    • 如:Order类具有状态和方法,状态是私有的,只能通过它的方法间接访问;
  • 易于理解、维护、测试和扩展;

1.4 关于领域驱动设计

领域驱动设计(DDD)是对面向对象设计的改进,是开发复杂业务逻辑的一种方法。其基本元素如下:

  • 实体(entity):具有持久化ID的对象。具有相同属性值的两个实体仍然是不同的对象;
  • 值对象(value object):作为值集合的对象。具有相同属性值的两个值对象可以互换使用;
  • 工厂(factory):负责实现对象创建逻辑的对象或方法,该逻辑过于复杂,无法由类的构造函数直接完成。它还可以隐藏被实例化的具体类。工厂方法一般可实现为类的静态方法;
  • 存储库(repository):用来访问持久化实体的对象,储存库也封装了访问数据库的底层机制;
  • 服务(service):实现不属于实体或值对象的业务逻辑对象;

2. 使用聚合模式设计领域模型

传统领域模型缺少每个业务对象的明确边界,DDD聚合旨在解决此问题。

2.1 聚合拥有明确的边界

聚合模式:将领域模型组织为聚合的集合,每个聚合都是可以作为一个单元进行处理的一组对象构成的图。

Order 聚合及其边界

Order 聚合及其边界

  • 聚合代表了一致的边界
    • 更新整个聚合可以解决一致性问题;
  • 识别聚合是关键
    • 在驱动领域设计中,设计领域模型的关键部分是识别聚合,以及它们的边界和根;

2.2 聚合规则

聚合规则可以确保聚合是一个可以强制执行各种不变量约束的自包含单元。

  • 规则一:只引用聚合根
    • 聚合根是聚合中唯一可以由外部类引用的部分;客户端只能通过调用聚合根上的方法来更新聚合;
    • 如:服务使用储存库从数据库加载聚合并获取聚合根的引用;
  • 规则二:聚合间的引用必须使用主键
    • 如:Order使用consumerId引用其Consumer而不是直接引用Consumer对象;
  • 规则三:在一个事务中,只能创建或更新一个聚合
    • 这个约束可以确保单个事务的范围不超越服务的边界;还满足大多数NoSQL数据库的受限事务模型;
    • 这个规则让创建或更新多个聚合的操作变得更加复杂,但可以通过Saga解决;

事务只能创建或更新单个聚合


2.3 聚合的颗粒度

  • 由于每个聚合的更新都是序列化的,因此更细颗粒度的聚合间提高应用程序能同时处理的请求数量,从而提高可扩展性;
  • 另一方面,因为聚合是事务的范围,所以可能需要定义更大的聚合以使特定的聚合更新操作满足事务的原子性;
  • 因此,在开发领域模型时,必须做出的关键决策是决定每个聚合的大小;

2.4 使用聚合设计业务

  • 在典型的微服务中,大部分业务逻辑由聚合组成;其余业务逻辑存在与领域服务和Saga中;
  • Saga编排本地事务的序列,以确保数据的一致性;
  • 服务是业务逻辑的入口,由入站适配器调用;
  • 服务使用存储库从数据库中检索聚合或将聚合保存到数据库;
  • 每个存储库都由访问数据库的出站适配器实现;

2.5 Order Service基于聚合设计的业务逻辑

Order Service基于聚合设计的业务逻辑

  • 业务逻辑由Order聚合、OrderService服务类、OrderRepository和一个或多个Saga组成;
  • OrderService调用OrderRepository来保存和加载Order;
  • 对于能在服务内部完成处理的简单请求,服务直接更新Order聚合;
  • 如果更新请求跨越多个服务,OrderService将创建一个Saga;

3. 发布领域事件

领域事件:聚合在被创建时,或发生其他重大更改时发布领域事件。

3.1 领域事件的应用场景

  • 使用基于编排的Saga维护服务之间的数据一致性【第四章】;
  • 通知维护数据副本的服务,源数据已经发生了更改;这种方法称为命令查询职责隔离(CQRS)【第七章】;
  • 通过Webhook或消息代理通知不同的应用程序,以触发下一个业务流程;
  • 按顺序通知同一应用程序的不同组件;
  • 向用户发送短信或电子邮件通知,告诉他们订单发货、航班延误等消息;
  • 监控领域事件以验证应用程序是否正常运行;
  • 分析领域事件,为用户行为建模;

3.2 领域事件的特点

  • 命名领域事件时,往往选择动词的过去分词;
  • 领域事件的每个属性都是原始值或值对象;
    • 如:OrderCreated事件类具有orderId属性;
  • 领域事件通常具有元数据,如事件ID和时间戳;
  • 元数据可以是事件对象的一部分,可能在超类中定义;

OrderCreated事件是领域事件的一个例子

  • DomainEvent接口是一个标识接口,用于将类标识为领域事件;
  • OrderDomainEvent是Order聚合发布的事件的标识接口(如OrderCreated);
  • DomainEventEnvelope是一个包含事件元数据和事件对象的类;

3.3 事件增强

当OrderCreated的事件接收方需要订单的详细信息时,一种办法是从Order Service中检索该信息,让事件接收方查询聚合服务,缺点是会产生服务请求的开销;

另一种方案是事件增强:

  • 事件包含接收方需要的信息
  • 缺点:可能会使领域事件的稳定性降低;每当接收方的需求发生改变时,事件类都可能需要更改;可能会降低可维护性;

在这里插入图片描述

3.4 识别领域事件

可以使用事件风暴方法,其结果是一个以事件为中心的领域模型,它由聚合和事件组成;包括以下三个步骤:

  1. 头脑风暴:请求领域专家集体讨论领域事件;
  2. 识别事件触发器:请求领域专家确定每个事件的触发器(如:用户操作、外部系统、另一个领域事件、时间的流逝等);
  3. 识别聚合:请求领域专家识别那些使用命令的聚合并发出相应的事件;

3.5 生成领域事件

在聚合和调用它的服务(或类)之间分配职责。

  • 服务可以使用依赖注入来获取对消息传递API的引用,从而轻松发布事件;
  • 只要状态发生变化,聚合就会生成事件并将它们返回给服务;
  • 聚合可以通过以下方法将事件返回给服务:

在聚合方法的返回值中包括一个事件列表


该服务调用聚合根方法,然后发布事件;


聚合根在一个内部字段中累积保存事件:然后服务检索这些事件并发布它们;

3.6 发布领域事件

服务必须使用事务性消息来发布事件,以确保领域事件是作为更新数据库中聚合的事务的一部分对外发布;

Eventuate Tram框架提供DomainEventPublisher接口

DomainEventPublisher接口
让服务实现AbstractAggregateDomainEventPublisher的子类:它为发布领域事件提供了类型安全的接口;

AbstractAggregateDomainEventPublishe接口

实现AbstractAggregateDomainEventPublisher子类

3.7 消费领域事件

领域事件是接收方使用更高级的API,如:Eventuate Tram框架的DomainEventDispatcher等。其可以将领域事件调度到适当的处理程序方法。

  • 每当餐馆的菜单更新时,KitchenServiceEventConsumer都会订阅Restaurant Service发布事件;
  • 它负责使Kitchen Service的数据副本保持最新;

4. Kichen Service的业务逻辑

该服务的主要功能是负责实现餐馆的订单管理功能。其两个主要聚合是Restaurant和Ticket;

4.1 Kichen Service的设计

Kitchen Service的设计

  • 两个聚合:
    • Restaurant:知道餐馆的菜单和营业事件,并可以验证订单;
    • Ticket:工单烹饪完成后由送餐员负责派送;
  • 核心业务:
    • KitchenService:业务入口,定义了创建和更新Restaurant及Ticket聚合的方法;
    • TicketRepository:定义了持久化Tickets的方法;
    • RestaurantRepository:定义了持久化Restaurants的方法;
  • 三个入站适配器:
    • REST API:餐馆工作人员通过他们的用户界面调用这些REST API;
    • KitchenServiceCommandHandler:由Saga调用的基于异步请求 / 响应的API;它调用KitchenService来创建和更新Ticket;
    • KitchenServiceEventConsumer:订阅Restaurant Service发布的事件;它调用KitchenService来创建和更新Restaurant聚合;
  • 两个出站适配器:
    • DB Adapter:实现TicketRepository和RestaurantRepository接口并访问数据库;
    • DomainEventPublishingAdapter:实现DomainEventPublisher接口并发布Ticket领域事件;

4.2 Ticket类的结构

该类使用JPA进行持久化,并映射到TICKETS表。


Ticket类的结构

4.3 Ticket聚合的行为


Ticket的一些方法

  • create():创建Ticket的工厂方法;
  • accept():餐馆已接收订单;
  • preparing():餐馆已开始准备订单,意味着订单无法再更改或取消;
  • readyForPickup():订单可以派送;

4.4 KitchenService的领域服务

KitchenService由服务入站适配器调用;定义了用于更改订单状态的各种方法(如accept()、reject()、preparing()等);每个方法加载指定的聚合,在聚合根上调用相应的方法,并发布领域事件;如下accept()方法所示:

accept()方法更新Ticket
accept()方法的两个参数

  • orderId:要接受订单的ID;
  • readyBy:订单可被派送的预计时间;

4.5 KitchenServiceCommandHandler类

KitchenServiceCommandHandler类是一个适配器,负责处理Order Service实现的各种Saga发送的命令式消息;

KitchenServiceCommandHandler类


5. Order Service的业务逻辑

5.1 Order Service的设计

Order Service的设计

  • 几个入站适配器:
    • REST API:供消费者利用用户界面调用的REST API;它调用OrderService来创建和更新Order;
    • OrderEventConsumer:订阅Restaurant Service发布的活动;它调用OrderService来创建和更新其Restaurant副本;
    • OrderCommandHandlers:由Saga调用的基于异步请求 / 相应的API;它调用OrderService来更新Order;
    • SagaReplyAdapter:订阅Saga回复通道并调用Saga;
  • 一些出站适配器:
    • DB Adapter:实现OrderRepository接口并访问Order Service的数据库;
    • DomainEventPublishingAdapter:实现DomainEventPublisher接口并发布Order领域事件;
    • OutboundCommandMessageAdapter:实现CommandPublisher接口并向Saga参与方发送命令式消息;

5.2 Order聚合的结构

Order类是Order聚合的根;Order聚合还包括了值对象,如:OrderLineItem、DeliveryInfo和PaymentInfo。

Order聚合的设计
Order类和它的字段

此类使用JPA持久化,并映射到ORDERS表。


Order类和它的字段

5.3 Order聚合状态机

为了创建或更新订单,Order Service必须使用Saga与其他服务协作。

Order聚合状态机
创建Order过程中调用的Order方法

创建Order过程中调用的方法

更新Order需要调用的方法


更新Order需要调用的方法

5.4 OrderService类

该类定义了用于创建和更新Orders的方法。

OrderService类


6. 微服务与单体应用程序的业务逻辑异同点

  • 相同点
    • 由诸如服务、JPA支持的实体类和存储库等这样的类组成;
  • 不同点
    • 领域模型被组织为一组DDD聚合,在其上可以施加各种约束;
    • 与传统的对象模型不同,不同聚合中的类之间的引用是基于主键而不是对象引用;
    • 事务只能创建或更新单个聚合;聚合在状态发生变化时会发布领域事件;
    • 服务通常使用Saga来维护多个服务之间的数据一致性;

7. 本章小结

  • 事务脚本模式通常是实现简单业务的好办法。但在实现复杂的业务逻辑时,应该考虑使用面向对象的领域模型模式;
  • 设计服务的业务逻辑的好办法是使用DDD聚合。DDD聚合很有用,因为它们把领域模型模块化,消除了服务之间对象的直接引用,并确保每个ACID事务都在服务内;
  • 创建或更新聚合时应发布领域事件。领域事件具有广泛的用途。第4章讨论了如何实现协同式Saga。第7章中将讨论如何使用领域事件来更新从其他服务复制来的数据。领域事件的订阅者还可以通知用户和其他应用程序,并将WebSocket消息发布到用户的浏览器。

最后

新人制作,如有错误,欢迎指出,感激不尽!
欢迎关注公众号,会分享一些更日常的东西!
如需转载,请标注出处!

这篇关于《微服务架构设计模式》读书笔记 | 第5章 微服务架构中的业务逻辑设计的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/385660

相关文章

如何开启和关闭3GB模式

https://jingyan.baidu.com/article/4d58d5414dfc2f9dd4e9c082.html

十四、观察者模式与访问者模式详解

21.观察者模式 21.1.课程目标 1、 掌握观察者模式和访问者模式的应用场景。 2、 掌握观察者模式在具体业务场景中的应用。 3、 了解访问者模式的双分派。 4、 观察者模式和访问者模式的优、缺点。 21.2.内容定位 1、 有 Swing开发经验的人群更容易理解观察者模式。 2、 访问者模式被称为最复杂的设计模式。 21.3.观察者模式 观 察 者 模 式 ( Obser

通信系统网络架构_2.广域网网络架构

1.概述          通俗来讲,广域网是将分布于相比局域网络更广区域的计算机设备联接起来的网络。广域网由通信子网于资源子网组成。通信子网可以利用公用分组交换网、卫星通信网和无线分组交换网构建,将分布在不同地区的局域网或计算机系统互连起来,实现资源子网的共享。 2.网络组成          广域网属于多级网络,通常由骨干网、分布网、接入网组成。在网络规模较小时,可仅由骨干网和接入网组成

springboot家政服务管理平台 LW +PPT+源码+讲解

3系统的可行性研究及需求分析 3.1可行性研究 3.1.1技术可行性分析 经过大学四年的学习,已经掌握了JAVA、Mysql数据库等方面的编程技巧和方法,对于这些技术该有的软硬件配置也是齐全的,能够满足开发的需要。 本家政服务管理平台采用的是Mysql作为数据库,可以绝对地保证用户数据的安全;可以与Mysql数据库进行无缝连接。 所以,家政服务管理平台在技术上是可以实施的。 3.1

微服务中RPC的强类型检查与HTTP的弱类型对比

在微服务架构中,服务间的通信是一个至关重要的环节。其中,远程过程调用(RPC)和HTTP是两种最常见的通信方式。虽然它们都能实现服务间的数据交换,但在类型检查方面,RPC的强类型检查和HTTP的弱类型之间有着显著的差异。本文将深入探讨这两种通信方式在类型检查方面的优缺点,以及它们对微服务架构的影响。 一、RPC的强类型检查 RPC的强类型检查是其核心优势之一。在RPC通信中,客户端和服务端都使

响应式架构

介绍 响应式架构(Reactive Architecture)是一种面向服务和事件的系统设计方法,旨在提高系统的可扩展性、弹性和容错能力。它适用于构建分布式系统,特别是在云环境和微服务架构中。响应式架构的核心理念是通过事件驱动和数据流来实现各个组件之间的解耦,从而提高整个系统的响应能力和可靠性。 响应式架构的主要特点包括: 响应性:系统能够快速响应外部事件和内部变化,确保在各种负载和故障情

中国341城市生态系统服务价值数据集(2000-2020年)

生态系统服务反映了人类直接或者间接从自然生态系统中获得的各种惠益,对支撑和维持人类生存和福祉起着重要基础作用。目前针对全国城市尺度的生态系统服务价值的长期评估还相对较少。我们在Xie等(2017)的静态生态系统服务当量因子表基础上,选取净初级生产力,降水量,生物迁移阻力,土壤侵蚀度和道路密度五个变量,对生态系统供给服务、调节服务、支持服务和文化服务共4大类和11小类的当量因子进行了时空调整,计算了

SpringCloud - 微服务

1、微服务介绍         参考: 微服务百度百科 1.1 概念         微服务(或称微服务架构)是一种云原生架构方法,在单个应用中包含众多松散耦合且可单独部署的小型组件或服务。 这些服务通常拥有自己的技术栈,包括数据库和数据管理模型;通过一个REST API、事件流和消息代理组合彼此通信;以及按照业务能力进行组织,具有通常称为有界上下文的服务分隔线。         微服务特

Builder模式的实现

概念 在创建复杂对象时,将创建该对象的工作交给一个建造者,这个建造者就是一个Builder。在日常的开发中,常常看到,如下这些代码: AlertDialog的实现 AlertDialog.Builder builder = new AlertDialog.Builder(context);builder.setMessage("你好建造者");builder.setTitle