DDD实战课
欧创新
人保高级架构师
立即订阅
4865 人已学习
课程目录
已完结 23 讲
0/2登录后,你可以任选2讲全文学习。
开篇词 (1讲)
开篇词 | 学好了DDD,你能做什么?
免费
基础篇 (5讲)
01 | 领域驱动设计:微服务设计为什么要选择DDD?
02 | 领域、子域、核心域、通用域和支撑域:傻傻分不清?
03 | 限界上下文:定义领域边界的利器
04 | 实体和值对象:从领域模型的基础单元看系统设计
05 | 聚合和聚合根:怎样设计聚合?
进阶篇 (6讲)
06 | 领域事件:解耦微服务的关键
07 | DDD分层架构:有效降低层与层之间的依赖
08 | 微服务架构模型:几种常见模型的对比和分析
09 | 中台:数字转型后到底应该共享什么?
10 | DDD、中台和微服务:它们是如何协作的?
答疑:有关3个典型问题的讲解
实战篇 (10讲)
11 | DDD实践:如何用DDD重构中台业务模型?
12 | 领域建模:如何用事件风暴构建领域模型?
13 | 代码模型(上):如何使用DDD设计微服务代码模型?
14 | 代码模型(下):如何保证领域模型与代码模型的一致性?
15 | 边界:微服务的各种边界在架构演进中的作用?
16 | 视图:如何实现服务和数据在微服务各层的协作?
17 | 从后端到前端:微服务后,前端如何设计?
18 | 知识点串讲:基于DDD的微服务设计实例
19 | 总结(一):微服务设计和拆分要坚持哪些原则?
20 | 总结(二):分布式架构关键设计10问
结束语 (1讲)
结束语 | 所谓高手,就是跨过坑和大海!
DDD实战课
登录|注册

06 | 领域事件:解耦微服务的关键

欧创新 2019-10-25
你好,我是欧创新。今天我们来聊一聊“领域事件(Domain Event)”。
在事件风暴(Event Storming)时,我们发现除了命令和操作等业务行为以外,还有一种非常重要的事件,这种事件发生后通常会导致进一步的业务操作,在 DDD 中这种事件被称为领域事件。
这只是最简单的定义,并不能让我们真正理解它。那到底什么是领域事件?领域事件的技术实现机制是怎样的?这一讲,我们就重点解决这两个大的问题。

领域事件

领域事件是领域模型中非常重要的一部分,用来表示领域中发生的事件。一个领域事件将导致进一步的业务操作,在实现业务解耦的同时,还有助于形成完整的业务闭环。
举例来说的话,领域事件可以是业务流程的一个步骤,比如投保业务缴费完成后,触发投保单转保单的动作;也可能是定时批处理过程中发生的事件,比如批处理生成季缴保费通知单,触发发送缴费邮件通知操作;或者一个事件发生后触发的后续动作,比如密码连续输错三次,触发锁定账户的动作。
那如何识别领域事件呢?
很简单,和刚才讲的定义是强关联的。在做用户旅程或者场景分析时,我们要捕捉业务、需求人员或领域专家口中的关键词:“如果发生……,则……”“当做完……的时候,请通知……”“发生……时,则……”等。在这些场景中,如果发生某种事件后,会触发进一步的操作,那么这个事件很可能就是领域事件。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《DDD实战课》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(52)

  • 阿神
    微服务内的领域事件我建议少用,增加复杂性了

    作者回复: 我跟你的观点一样。

    2019-10-25
    4
    9
  • 杨杰
    关于领域事件有几个问题:
    1、如果采用了主流的消息队列(如rabbitmq,kafka,rocketmq),是否领域事件还需要持久化?
    2、对于领域事件的内容,是否需要把所有变化(或绝大多数)的内容都保存到事件里面(比如保单里面的所有内容)?这样的话这个这个领域事件会不会比较大?
    3、关于领域事件还有一种方案就是基于数据库cdc的方式,在系统中有大量领域事件的场景下,是否cdc的形式更加灵活一点?

    作者回复: 第一个问题:虽然这些消息队列自身有持久化的功能,但是中间过程,或者在订阅到数据后,在处理之前出问题,需要进行数据对账,这样就没法找到发布时和处理后的数据版本。关键的业务数据我建议还是落库比较好。
    第二个问题:事件实体的业务数据还是按需发布比较好,避免不必要的业务信息泄露。
    第三个问题:CDC的设计方式比较简单,属于数据库底层的技术,不会对上层应用产生太多的影响。

    2019-10-28
    1
    4
  • zj
    spring提供的事件机制我感觉也可以啊,可以用在微服务内

    作者回复: 现在的技术路线很多,只要能保证在一个事务在修改多个聚合数据时,能保证数据一致性就可以使用。

    2019-11-21
    2
  • Geek_a91670
    "微服务内应用服务,可以通过跨聚合的服务编排和组合,以服务调用的方式完成跨聚合的访问,这种方式通常应用于实时性和数据一致性要求高的场景。这个过程会用到分布式事务,以保证发布方和订阅方的数据同时更新成功。"
    -------服务类的领域事件怎么还牵扯到分布式事务了呢?

    作者回复: 如果一个领域事件会同时修改多个聚合之间的数据的话,可能会存在不同聚合内数据一致性的问题。事件总线的方式可以以同步或者异步的方式来保证聚合之间数据的一致性。多个聚合之上的应用服务也可以来协调这种数据一致性,但由于是跨聚合,需要保证多个聚合同时成功,这可以用事务的方式来实现。但是由于在同一个微服务内的进程内,出错的概率要比微服务之间小得多。

    2019-10-31
    1
    1
  • 观弈道人
    欧老师你好:事件有没有被消费成功(消费端成功拿到消息或消费端业务处理成功),一般如何通知到消息生产端?谢谢。

    作者回复: 因为事件发布方有事件实体的原始的持久化数据,事件订阅方也有自己接收的持久化数据。一般可以通过定期对账的方式检查数据的一致性。

    2019-10-28
    1
    1
  • 刘哲
    老师,事件总线这种工具可能在国企用的多些,在互联网公司,服务间通讯,下行用dubbo,springcloud,上行rocketMQ,这是一般操作,我想写一篇文章借用您的DDD思想,使用互联网公司常用的一些rpc工具来处理领域事件,不知您是否同意?

    作者回复: 你提到的事件总线是不是企业服务总线(ESB)。事件总线跟它有点不太一样的。思想是可以借鉴的哈,但是内容要考虑一下极客的版权。

    2019-12-11
  • itrickzhang
    欧老师我想问下,微服务之间用消息中间件通讯,那么注册中心是否是微服务设计的一个鸡肋

    作者回复: 不是这样的。消息中间件主要用于微服务之间的异步处理,其实很多场景还是实时服务调用的。

    2019-12-11
  • Geek_aa8017
    为什么事件在发送方和订阅方都要持久化呢?这样会不会太繁琐了,能只在发送方持久化吗

    作者回复: 只要能够保证源端和目的端对账的要求,可以不必两端都持久化。

    2019-12-09
  • 冷たい風
    老师你好,基于文档中缴费通知单的例子我请教下以下俩个问题:
    1、发送缴费通知事件是在应用层发出还是应该在领域层发出呢,还是无论在哪里发送都可以,DDD没有这个强制的规范?
    2、例子中处理缴费通知和发送事件的方法是二个独立分开的方法,那如果发送事件的上下文数据是需要处理缴费通知逻辑里面的数据,那这种方式就行不通,那是不是就只能在领域服务层处理缴费通知逻辑完成后也在领域服务层发送领域事件?

    作者回复: 1、都可以做,可以根据你的使用习惯。
    2、你可以在应用服务里调用两个服务的,一个用于事件处理,事件处理完成后调用另一个用于事件发布。

    2019-12-03
  • vivi
    老师,领域事件和CQRS里面的COMMAND,什么关系呢?
    EVENT BUS和COMMAND BUS的联系是什么呢,感觉是一套东西。

    作者回复: 是差不多的东西

    2019-11-26
  • surpass2007
    请问为什么微服务内的领域事件要少用呢?如果单纯的使用内部事件的方式,不引入复杂的消息总线,是不是不会增加太大的复杂性呀

    作者回复: 并不是不可以用哈,场景不复杂能接受的话,也是可以用的。主要是服务之间的关系不那么清晰,不像服务之间调用那么直接。

    2019-11-13
  • 张 振
    问个额外的问题:生成保单之后,佣金和收付事件,可不可以异步去完成?

    作者回复: 可以的啊。

    2019-11-13
  • JRich
    对这里的事件总线有一些疑惑,请问老师有具体的实现吗?

    作者回复: 不知道有什么疑惑哈。你可以去网上搜一下Eventbus,有不少的实现方式。

    2019-11-12
  • sqyao
    请问老师,在要求数据强一致性的分布式场景下,是不是建议使用分布式事务来实现,有其他的解决方案吗?😊😊

    作者回复: 目前来看主要是分布式事务的方式。

    2019-11-11
    1
  • ZIxuAN
    老师,有没有实际应用中的代码发到github上看下,主要想看下项目结构,聚合根是怎么维护生命周期的以及事件的最终一致性是怎么做的。

    作者回复: 代码目录结构后面会有专门的一节来讲,这个结构是我们项目过程总结出来的。个人感觉DDD主要提供的是一种思想,在战术实施过程可以根据自己的理解采用最合适的方式来实现。

    2019-11-10
  • 嘉嘉☕
    微服务内应用服务,可以通过跨聚合的服务编排和组合,以服务调用的方式完成跨聚合的访问,这种方式通常应用于实时性和数据一致性要求高的场景。这个过程会用到分布式事务,以保证发布方和订阅方的数据同时更新成功。

    老师好,这段第一句说“微服务内....”,所以下文中提到的分布式事务,是不是应该就是事务,不是分布式事务?

    作者回复: 这种情形很特殊,由于一个聚合一个仓储,在仓储内一次修改或者创建聚合内的所有数据。实际上在进行跨聚合数据提交的时候,是在同一进程的事务。但是它与微服务之间的事务不太一样,它是在同一个微服务内,而这种微服务内的数据因为解耦的关系,不同聚合之间的数据隔离性比较高,因此有别于一般的事务。

    2019-11-08
  • onlyone
    里面的图是用的什么软件画的?谢谢

    作者回复: visio😀

    2019-11-07
  • Nick
    看了一下关于事件数据持久化的方案二,意思是每个服务都要记录自己发布过的事件和收到过的事件通知么? 这样事件就会分散到很多个服务中,如果要做整个系统的对账,岂不是很麻烦?

    作者回复: 分散并且订阅方多的话,是有点麻烦。跟数据迁移一样,可以选择关键数据对账。
    两种方案各有利弊。

    2019-11-06
    1
  • Geek_1c00cb
    老师,请教个问题。最近想做重构,先发动大家对各个模块做了梳理,然后想先用四色模型建模,初步分析,但是对于事件驱动的业务如何用四色模型建模,尤其角色这个,指场景吗?

    作者回复: 我没有用过四色模型哈。
    建模的时候,你是不是可以把领域事件驱动 ,当成一种特殊的服务调用呢,只不过是异步化了。

    2019-11-05
  • 星极
    老师您好,我有两个问题
    1. 第1部分 “微服务内的领域事件”最后一段说到:“微服务内应用服务,可以通过跨聚合的服务编排和组合,以服务调用的方式完成跨聚合的访问,这种方式通常应用于实时性和数据一致性要求高的场景。这个过程会用到分布式事务,以保证发布方和订阅方的数据同时更新成功。” ,有点不明白,微服务内的领域事件怎么会用到分布式事务?保证发布方和订阅方的数据都更新成功只要让消息中间件保证提交成功的消息一定被消费就行了吧?
    2. 第5部分 “事件接收和处理”的例子里用户付款是在哪个阶段完成的

    作者回复: 微服务内主要是因为跨聚合了。一个聚合一个仓储,在一次修改多个聚合的时候,可能会存在数据不一致的情况,所以用事件总线或者分布式事务。
    付款是在收到缴费通知单后,在收款微服务完成的。

    2019-11-05
收起评论
52
返回
顶部