《微服务架构设计模式》读书笔记 | 第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

相关文章

mybatis的整体架构

mybatis的整体架构分为三层: 1.基础支持层 该层包括:数据源模块、事务管理模块、缓存模块、Binding模块、反射模块、类型转换模块、日志模块、资源加载模块、解析器模块 2.核心处理层 该层包括:配置解析、参数映射、SQL解析、SQL执行、结果集映射、插件 3.接口层 该层包括:SqlSession 基础支持层 该层保护mybatis的基础模块,它们为核心处理层提供了良好的支撑。

百度/小米/滴滴/京东,中台架构比较

小米中台建设实践 01 小米的三大中台建设:业务+数据+技术 业务中台--从业务说起 在中台建设中,需要规范化的服务接口、一致整合化的数据、容器化的技术组件以及弹性的基础设施。并结合业务情况,判定是否真的需要中台。 小米参考了业界优秀的案例包括移动中台、数据中台、业务中台、技术中台等,再结合其业务发展历程及业务现状,整理了中台架构的核心方法论,一是企业如何共享服务,二是如何为业务提供便利。

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

【区块链 + 人才服务】可信教育区块链治理系统 | FISCO BCOS应用案例

伴随着区块链技术的不断完善,其在教育信息化中的应用也在持续发展。利用区块链数据共识、不可篡改的特性, 将与教育相关的数据要素在区块链上进行存证确权,在确保数据可信的前提下,促进教育的公平、透明、开放,为教育教学质量提升赋能,实现教育数据的安全共享、高等教育体系的智慧治理。 可信教育区块链治理系统的顶层治理架构由教育部、高校、企业、学生等多方角色共同参与建设、维护,支撑教育资源共享、教学质量评估、

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

【区块链 + 人才服务】区块链集成开发平台 | FISCO BCOS应用案例

随着区块链技术的快速发展,越来越多的企业开始将其应用于实际业务中。然而,区块链技术的专业性使得其集成开发成为一项挑战。针对此,广东中创智慧科技有限公司基于国产开源联盟链 FISCO BCOS 推出了区块链集成开发平台。该平台基于区块链技术,提供一套全面的区块链开发工具和开发环境,支持开发者快速开发和部署区块链应用。此外,该平台还可以提供一套全面的区块链开发教程和文档,帮助开发者快速上手区块链开发。

业务协同平台--简介

一、使用场景         1.多个系统统一在业务协同平台定义协同策略,由业务协同平台代替人工完成一系列的单据录入         2.同时业务协同平台将执行任务推送给pda、pad等执行终端,通知各人员、设备进行作业执行         3.作业过程中,可设置完成时间预警、作业节点通知,时刻了解作业进程         4.做完再给你做过程分析,给出优化建议         就问你这一套下

系统架构设计师: 信息安全技术

简简单单 Online zuozuo: 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo :本心、输入输出、结果 简简单单 Online zuozuo : 文章目录 系统架构设计师: 信息安全技术前言信息安全的基本要素:信息安全的范围:安全措施的目标:访问控制技术要素:访问控制包括:等保

模版方法模式template method

学习笔记,原文链接 https://refactoringguru.cn/design-patterns/template-method 超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。 上层接口有默认实现的方法和子类需要自己实现的方法