微服务架构谈(4):领域事件-解耦微服务的关键

本文涉及的产品
云原生网关 MSE Higress,422元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: 微服务架构谈(4):领域事件-解耦微服务的关键

在领域建模时,我们发现除了命令和操作等业务行为以外,还有一类非常重要的事件。这类事件发生后通常会触发进一步的业务操作,在DDD中这类事件被称为领域事件(Domain Event)。


那到底什么是领域事件?领域事件驱动设计的技术实现机制是怎样的?我们这一章将重点讲解这两个问题。


1 领域事件

领域事件是领域模型非常重要的一部分,用于表示领域中发生的事件。一个领域事件往往会导致进一步的业务操作,它在实现领域模型解耦的同时,还有助于形成完整的业务操作闭环。

举例来说,领域事件可以是业务流程的一个步骤,比如投保业务缴费完成后,触发投保单转保单的动作;也可以是定时批处理过程中发生的事件,比如批处理生成季缴保费通知单,触发缴费邮件通知操作;还可以是一个事件发生后触发的后续动作,比如密码连续输错三次,触发锁定账户的动作。


那在领域建模时,如何识别和捕捉这些领域事件呢?

在用户旅程或者场景分析时,我们需要捕捉业务人员、需求分析人员以及领域专家口中的这些具有前后动作关系的关键词,比如:“如果发生⋯⋯,则⋯⋯”“当做完⋯⋯时,请通知⋯⋯”“发生⋯⋯时,则⋯⋯”等。在这些业务场景中,如果发生某种事件后,会触发进一步的业务操作,那么这个事件很可能就是领域事件。

领域事件采用事件驱动架构(Event-Driven Architecture,EDA)设计,可以切断领域模型之间的强依赖关系,在领域事件发布后,事件发布方不必关心订阅方的事件处理是否成功。这样就可以实现领域模型的解耦,维护领域模型的独立性。当领域模型映射到微服务时,领域事件就可以解耦微服务,这时微服务之间的数据就可以不再要求强一致性,而是基于最终一致性。


再回到具体的业务场景,我们发现有的领域事件发生在微服务内的聚合之间,有的发生在微服务之间,还有两者皆有的场景。一般来说,跨微服务的领域事件会相对较多。在微服务设计时,不同场景下的领域事件的处理方式会不同。

与采用同步服务调用实现数据强一致性的机制不同,领域事件一般都会结合消息中间件和事件发布订阅的异步处理方式,实现数据最终一致性。

那么,领域事件处理为什么要采用最终一致性,而不是强一致性呢?


我们先一起回顾一下第8章的内容,聚合有一个重要设计原则:“在边界之外使用最终一致性。”如果在一次事务提交中,修改的数据超出了一个聚合的边界,简单点说就是一笔交易,如果同时涉及多个聚合的数据更新,那么就可以采用数据最终一致性。


1.1 微服务内的领域事件

在微服务内发生领域事件,如果同时更新多个聚合数据时,你需要确保多个聚合数据的一致性。按照DDD“一次事务只更新一个聚合”的原则,你可以引入事件总线(Event Bus),通过事件总线来实现微服务内多聚合数据的最终一致性,或者采用事务机制保证数据强一致性。

在采用事件总线进行领域事件处理时,可以根据需要完成领域事件实体的构建和事件数据持久化,然后发布方聚合会将领域事件数据发布到事件总线,由订阅方聚合接收领域事件数据后完成后续业务处理。事件总线的设计方式,可能会增加微服务开发的复杂度,需要结合应用的复杂度和收益进行综合考虑。

你可能会问,在同一个微服务内,为什么一次事务更新多个聚合数据时,要用事件总线或事务机制呢?


这是因为聚合是微服务内最小的业务功能单元。为了保证聚合内数据更新时符合聚合内固定的业务规则,在一次事务提交时通常会将聚合内所有变更的对象数据作为整体,通过聚合领域服务或聚合根方法一次通过仓储完成数据持久化操作。如果在一次交易中需要同时更新多个聚合数据,那么每一个聚合就是一个独立的数据提交单元,我们需要确保多个聚合数据都能在这个交易中成功提交并更新,以保证不同聚合数据的一致性。而基于事件总线的异步化机制,就可以保证微服务内聚合之间数据提交时的最终一致性。


如果不采用事件总线的最终数据一致性机制,其实你也可以采用事务机制保证数据强一致性。比如在应用服务中增加事务控制,在对多个聚合的领域服务进行组合和编排时,通过事务机制来确保多个聚合在提交数据时实现数据强一致性。这种方式一般应用于实时性和数据一致性要求高的业务场景,但采用事务机制可能会出现系统性能损耗。


1.2 微服务之间的领域事件

跨微服务的领域事件可以在不同限界上下文,或领域模型之间实现业务协作,其主要目的是实现微服务解耦,推动业务流程或者数据在不同子域或微服务之间流转。同时也可以减轻微服务之间同步服务访问的压力,避免当某个关键微服务无法提供服务时,出现雪崩效应。


领域事件发生在微服务之间的场景比较多,事件处理的机制也更加复杂。微服务之间的领域事件可以采用异步化的最终一致性设计。设计时要总体考虑领域事件的构建、发布和订阅、领域事件数据的持久化、消息中间件,甚至在事件数据持久化时可能还需要引入分布式事务等机制。


微服务之间的领域事件,也可以采用同步服务调用的强一致性设计,实现实时的数据和服务访问。其弊端就是需要引入分布式事务机制,以确保微服务之间的数据强一致性。但分布式事务机制会影响系统性能,同时增加微服务之间的耦合。

所以,应尽量减少微服务之间的同步服务调用方式,优先采用基于消息中间件的最终一致性设计。


2 领域事件案例

下面介绍一个与保险承保业务有关的领域事件的案例,以加深对领域事件的理解。

一个保单的生成,通常会经历很多业务子域、业务状态变更和跨微服务业务数据的传递。这个过程会产生很多领域事件,这些领域事件促成了保险业务数据、对象在不同的微服务和子域之间的流转和角色转换,如不同微服务或聚合之间的实体与值对象之间的转换。在图9-1中,我列出了几个关键流程,用来说明如何用领域事件驱动设计来驱动保险业务流程。


事件起点:客户购买保险,业务人员完成投保单录入,生成投保单,启动缴费动作。


1)投保微服务生成缴费通知单,发布第一个事件:缴费通知单已生成。将缴费通知单事件数据发布到消息中间件。收款微服务订阅缴费通知单事件,完成缴费操作。缴费通知单已生成领域事件结束。


2)收款微服务缴费完成后,发布第二个领域事件:缴费已完成。将缴费事件数据发布到消息中间件。原来的事件订阅方收款微服务这时则变成了事件发布方。原来的发布方投保微服务这时转换为缴费已完成事件的订阅方。投保微服务在收到缴费信息并确认缴费完成后,完成投保单转成保单的操作。缴费已完成领域事件结束。


3)投保微服务在投保单转保单完成后,发布第三个领域事件:保单已生成。将保单事件数据发布到消息中间件。保单微服务接收到保单数据后,完成保单数据保存操作。保单已生成领域事件结束。


4)保单微服务完成保单数据保存后,后面还会发生一系列的领域事件,以并发的方式将保单事件数据通过消息中间件分别发送到佣金、收付和再保等微服务,一直到财务,完成保单后续所有业务流程。这里就不详细展开了。



image.png


图1 保险承保过程中的领域事件分析


综上,通过领域事件驱动的异步化机制,可以推动业务流程和数据在各个不同业务领域和微服务之间的流转,实现领域模型和微服务的解耦,减轻微服务之间服务调用的压力,提升用户体验。

相关文章
|
5天前
|
缓存 负载均衡 JavaScript
探索微服务架构下的API网关模式
【10月更文挑战第37天】在微服务架构的海洋中,API网关犹如一座灯塔,指引着服务的航向。它不仅是客户端请求的集散地,更是后端微服务的守门人。本文将深入探讨API网关的设计哲学、核心功能以及它在微服务生态中扮演的角色,同时通过实际代码示例,揭示如何实现一个高效、可靠的API网关。
|
3天前
|
Cloud Native 安全 数据安全/隐私保护
云原生架构下的微服务治理与挑战####
随着云计算技术的飞速发展,云原生架构以其高效、灵活、可扩展的特性成为现代企业IT架构的首选。本文聚焦于云原生环境下的微服务治理问题,探讨其在促进业务敏捷性的同时所面临的挑战及应对策略。通过分析微服务拆分、服务间通信、故障隔离与恢复等关键环节,本文旨在为读者提供一个关于如何在云原生环境中有效实施微服务治理的全面视角,助力企业在数字化转型的道路上稳健前行。 ####
|
4天前
|
Dubbo Java 应用服务中间件
服务架构的演进:从单体到微服务的探索之旅
随着企业业务的不断拓展和复杂度的提升,对软件系统架构的要求也日益严苛。传统的架构模式在应对现代业务场景时逐渐暴露出诸多局限性,于是服务架构开启了持续演变之路。从单体架构的简易便捷,到分布式架构的模块化解耦,再到微服务架构的精细化管理,企业对技术的选择变得至关重要,尤其是 Spring Cloud 和 Dubbo 等微服务技术的对比和应用,直接影响着项目的成败。 本篇文章会从服务架构的演进开始分析,探索从单体项目到微服务项目的演变过程。然后也会对目前常见的微服务技术进行对比,找到目前市面上所常用的技术给大家进行讲解。
14 1
服务架构的演进:从单体到微服务的探索之旅
|
3天前
|
Cloud Native 安全 API
云原生架构下的微服务治理策略与实践####
—透过云原生的棱镜,探索微服务架构下的挑战与应对之道 本文旨在探讨云原生环境下,微服务架构所面临的关键挑战及有效的治理策略。随着云计算技术的深入发展,越来越多的企业选择采用云原生架构来构建和部署其应用程序,以期获得更高的灵活性、可扩展性和效率。然而,微服务架构的复杂性也带来了服务发现、负载均衡、故障恢复等一系列治理难题。本文将深入分析这些问题,并提出一套基于云原生技术栈的微服务治理框架,包括服务网格的应用、API网关的集成、以及动态配置管理等关键方面,旨在为企业实现高效、稳定的微服务架构提供参考路径。 ####
20 5
|
5天前
|
监控 API 微服务
后端技术演进:从单体架构到微服务的转变
随着互联网应用的快速增长和用户需求的不断演化,传统单体架构已难以满足现代软件开发的需求。本文深入探讨了后端技术在面对复杂系统挑战时的演进路径,重点分析了从单体架构向微服务架构转变的过程、原因及优势。通过对比分析,揭示了微服务架构如何提高系统的可扩展性、灵活性和维护效率,同时指出了实施微服务时面临的挑战和最佳实践。
23 7
|
4天前
|
Kubernetes 负载均衡 Cloud Native
云原生架构下的微服务治理策略
随着云原生技术的不断成熟,微服务架构已成为现代应用开发的主流选择。本文探讨了在云原生环境下实施微服务治理的策略和方法,重点分析了服务发现、负载均衡、故障恢复和配置管理等关键技术点,以及如何利用Kubernetes等容器编排工具来优化微服务的部署和管理。文章旨在为开发者提供一套实用的微服务治理框架,帮助其在复杂的云环境中构建高效、可靠的分布式系统。
18 5
|
4天前
|
负载均衡 监控 Cloud Native
云原生架构下的微服务治理策略与实践####
在数字化转型浪潮中,企业纷纷拥抱云计算,而云原生架构作为其核心技术支撑,正引领着一场深刻的技术变革。本文聚焦于云原生环境下微服务架构的治理策略与实践,探讨如何通过精细化的服务管理、动态的流量调度、高效的故障恢复机制以及持续的监控优化,构建弹性、可靠且易于维护的分布式系统。我们将深入剖析微服务治理的核心要素,结合具体案例,揭示其在提升系统稳定性、扩展性和敏捷性方面的关键作用,为读者提供一套切实可行的云原生微服务治理指南。 ####
|
5天前
|
监控 持续交付 Docker
Docker 容器化部署在微服务架构中的应用有哪些?
Docker 容器化部署在微服务架构中的应用有哪些?
|
5天前
|
监控 持续交付 Docker
Docker容器化部署在微服务架构中的应用
Docker容器化部署在微服务架构中的应用
|
5天前
|
安全 持续交付 Docker
微服务架构和 Docker 容器化部署的优点是什么?
微服务架构和 Docker 容器化部署的优点是什么?