基于领域事件实现微服务解耦

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 基于领域事件实现微服务解耦

基于领域事件实现微服务解耦


领域事件是解耦微服务的关键。


什么是领域事件


除了命令和操作等业务行为,还有一种非常重要的事件,这种事件通常会导致进一步的业务操作,在DDD(Domain Driven Design,领域驱动设计)中,这种事件叫做 领域事件。

领域事件可以是业务流程中的一个步骤。比如,投保业务缴费之后,投保单转为保单。支付成功后,生产商品订单。这里的支付就是一个领域事件。或者是一个事件发生后触发进一步操作, 比如,密码连续输入错误3次,账户锁定。这里的密码输入就是一个领域事件。


如何识别领域事件


用户旅程或者场景分析时,捕捉业务/需求人员或者领域专家口中的关键词:

  • 如果发生 。。。。,则。。。
  • 完。。。。的时候,请通知。。。
  • 发生。。。。时,则。。。

微服务之间的领域事件


跨微服务的领域事件会在不同界限上下文或领域模型直接实现业务协助,主要目的是实现微服务解耦。减轻微服务直接实现服务访问的压力。

举个例子:

当用户在购物车点击结算时,生成待付款订单,若支付成功,则更新订单状态为已支付,扣减库存,并推送捡货通知信息到捡货中心。

在你没有接触领域事件或EDA(事件驱动架构)之前,你会如何实现这个用例?肯定是简单直接的方法调用,在一个事务中分别去调用状态更新方法、扣减库存方法、发送捡货通知方法。

上面的实现有什么问题?

  • 试想一下,若现在要求支付成功后,需要额外发送一条付款成功通知到微信公众号,我们怎么实现?想必我们需要额外定义发送微信通知的接口并封装参数,然后再添加对方法的调用。这种做法虽然可以解决需求的变更,但很显然不够灵活耦合性强,也违反了OCP。
  • 将多个操作放在同一个事务中,使用事务一致性可以保证多个操作要么全部成功要么全部失败。在一个事务中处理多个操作,若其中一个操作失败,则全部失败。但是,这在业务上是不允许的。客户成功支付了,却发现订单依旧为待付款,这会导致纠纷的。
  • 违反了聚合的一大原则:在一个事务中,只对一个聚合进行修改。在这个用例中,很明显我们在一个事务中对订单聚合和库存聚合进行了修改。

如果基于领域事件如何实现?


领域事件建模


  1. 事件源    entry
  2. 事件对象 domainMessage  = 事件类型 eventTopic + 事件源  entry
  3. 事件监听器   subscribe 处理事件
  4. 事件分发器 注册监听器  JvmEventConsumer
  5. 生产消息 实时消费,producer中直接consume 或者 MQ的形式,异步消费

image.png

领域事件 = 事件发布 + 事件存储 + 事件分发 + 事件处理。


为啥基于领域事件驱动的设计能够实现系统解耦?


关键是因为居于事件驱动架构 【Event-Driven Architecture(事件驱动架构))】

事件驱动架构有三个特性:

  1. 异步
  2. 实时
  3. 彻底解耦

EDA 架构的核心是基于消息的发布订阅模式,通过发布订阅,消息消费方对于消息发送方而言是完全透明的,发送方只是把消息正常发送到消息中间件,其他的不关心, 及时发送消息的时候,消息接收方不可用,消息生产者仍然可以发送消息,这样实现了系统间的彻底解耦,不存在系统间的依赖。


总结


领域事件是 DDD 的重要概念,设计时需要关注领域事件,用领域事件来驱动业务流转,尽量采用事件的最终一致性,降低微服务直接的耦合,实现微服务间的解耦,维护领域模型的独立性和数据一致性。

相关文章
|
存储 关系型数据库 MySQL
微服务篇:物化来自实体事件的状态
通过从实体事件流中按顺序处理实体事件,可以将信息物化成一个有状态的表。每个实体事件都会被更新插入键/值表中,这样对于一个给定的键,表中表示的就是最新读到的事件。
|
负载均衡 NoSQL 安全
微服务 Spring Boot 整合Redis分布式锁 实现优惠卷秒杀 一人一单
高并发集群模式下,秒杀出现问题,如何解决,Redis 分布式锁来搞定!
271 0
微服务 Spring Boot 整合Redis分布式锁 实现优惠卷秒杀 一人一单
|
JSON 数据格式 微服务
Angular 实现类似微服务的效果
Angular 实现类似微服务的效果
Angular 实现类似微服务的效果
|
存储 监控 数据可视化
ELK搭建(一):实现分布式微服务日志监控
本次我们搭建的目标是通过ELK来收集微服务中的日志。本期主要以实操、快速搭建为主进行讲解,部分基础概念不做过多描述,后续会再单独出几期博客说明。更多ELK搭建可以关注本专栏,后续会持续输出。
347 0
ELK搭建(一):实现分布式微服务日志监控
|
消息中间件 SpringCloudAlibaba 监控
【springcloud alibaba】 一条龙服务实现微服务案例(下)
【springcloud alibaba】 一条龙服务实现微服务案例(下)
199 0
【springcloud alibaba】 一条龙服务实现微服务案例(下)
|
存储 SpringCloudAlibaba 负载均衡
【springcloud alibaba】 一条龙服务实现微服务案例(上)
【springcloud alibaba】 一条龙服务实现微服务案例
228 0
【springcloud alibaba】 一条龙服务实现微服务案例(上)
|
运维 Kubernetes Devops
通过云效 CI/CD 实现微服务全链路灰度
在微服务治理架构中,MSE 全链路灰度提供了虚拟泳道能力,极大的方便了测试、发布时的快速验证,能够帮助 Devops 同学减少保障半径、提升线上稳定性。同时,阿里云微服务引擎(MSE)也能给您带来全生命周期的、全方位的微服务治理、流量防护能力,保障您的线上稳定性,提升开发、运维效率。
通过云效 CI/CD 实现微服务全链路灰度
|
Java Nacos 开发者
GateWay实现转发真实微服务接口|学习笔记
快速学习GateWay实现转发真实微服务接口
218 0
|
NoSQL Java 数据库
微服务架构与SOA架构模式实现区别|学习笔记
快速学习微服务架构与SOA架构模式实现区别
120 0
|
负载均衡 Cloud Native Java
【云原生&微服务三】SpringCloud之Ribbon是这样实现负载均衡的(源码剖析@LoadBalanced原理)
【云原生&微服务三】SpringCloud之Ribbon是这样实现负载均衡的(源码剖析@LoadBalanced原理)
229 0
【云原生&微服务三】SpringCloud之Ribbon是这样实现负载均衡的(源码剖析@LoadBalanced原理)