浅谈「领域事件」实践

领域事件是DDD,Event Sourcing等架构中的一个重要概念。
基于工作环境中的一些实践经验,我总结了一些粗浅的体会。
文中不会有非常高深复杂的定义,只使用一些基本的概念。

领域事件定义

国外书籍中很少使用下定义的方式解释一个名词的含义。一般都会使用作诠释的方式:“领域事件可以怎样怎样”、“领域事件会带来什么什么”。

让我来下定义的话:领域事件是微服务系统中各服务通信的一种方式。和RPC类似,领域事件用于在服务之间交换信息,但领域事件并不追求实时一致性,仅要求数据的最终一致性。

各服务在一些关键有意义的业务节点完成后会发送领域事件,代表一些关键的动作「已完成」。因此领域事件的命名多采用过去分词,例如「订单已发送Order sent」「订单已取消Order canceled」。

领域事件有多种实现方式。我工作中使用到的方式是:将一些关键的、其他服务可能用到的信息,打包成一个结构体,以消息的形式,通过消息队列中间件,异步传输给系统中订阅该消息的服务。

领域事件带来的收益

介绍领域事件的书籍从不吝惜对领域事件优点的赞美。在此我针对各优点谈谈自己的感受。

增强服务自治性

这大概是领域事件最常被提及的优点了。何谓“自治性”?我的理解是:一个服务只需要关注自己,不与其他服务耦合的程度。单体服务不依赖其他任何服务,自治性最高;如果一个服务调用了大量其他服务的RPC,那么它的稳定性和业务逻辑必定受其他服务的影响,自治性稍差。

为什么能提升自治性?个人认为有以下原因:

首先领域事件一般使用消息队列实现,消息队列是异步的,不会阻塞调用。如果因一时网络原因消息无法传达,那么也会由消息组件重试。领域事件可以看做异步的非阻塞的由第三方保证最终送达的RPC,可靠性比普通的RPC更高。

另一点就是领域事件不必指定消息的接收方是谁。假设我们有这样的业务场景,A服务完成了某一动作后,需要通知B。如果我们使用RPC通信,后面业务扩展时增加了C,D服务需要通知,则实现时我们需要修改A的代码,A的业务逻辑可能还要受到C,D处理结果的影响。但是如果我们使用领域事件进行通信,则在新增C,D服务之后,让它们订阅A发出的事件即可,A服务完全不需要修改,不受其他服务的影响,提升了自治性。

回放系统动作

如果我们把系统看做一个状态机,则领域事件可以看做推动状态机转移状态的输入。领域事件是具有业务含义的,回放某一时间段的领域事件可以复现用户操作。通过数据库binlog回放也可以达到类似的效果,但binlog是没有业务语义的,回放结果没有准确的解读方式。

回放领域事件当然需要某种消息存储/检索机制,这里不做展开。

实践领域事件时的一些思考

  • 领域事件实时性
    领域事件可以保证最终一致性,但不能保证数据实时性。产生的时延是否是业务可以接受的?《实现领域驱动设计精粹》中进行了一个精妙的类比:在软件出现前,传统业务的执行流程是怎样的?流程步骤之间是否会有一定的时间差?如果领域事件导致的时延不超过无软件时业务流程的时延,那么这时延就是可以接受的。当然,实际生产环境中,说服用户接受这样的时延通常不是件容易的事情。

  • 领域事件定义
    领域事件有业务语义,这个业务语义所代表的动作,必须要有明确的定义。例如:在一个招聘系统中,目前只有“现场面试签到”这一个场景。那么这个动作完成以后,应该发出「面试已签到」领域事件,还是发出「现场面试已签到」的领域事件呢?如果是前者,那么后续新增的其他类型面试签到,也要发出这个领域事件。领域事件的业务语义必须得到准确的解释,从命名开始。领域事件表示的动作粒度也要在定义前就想好。

  • 领域事件管理
    目前我们有yAPI这样优秀的接口管理工具,但还没有合适的领域事件管理工具。领域事件和接口都是用于通信的手段,所以他们的含义,包括功能、每个字段含义等,必须得到准确的解释。否则当领域事件增加到一定规模,有人员更迭时,了解各个领域事件将成为恼火的事情。

  • 向领域事件改造
    EDA是一种时髦的架构,但并非所有服务一开始就会选用这种架构。一个单纯由RPC通信的系统,想要转型到通过领域事件通信会遇到很多问题。我们系统遇到的一个现实问题是:太多的接口可能会发送同一种领域事件,如果在所有可能的代码后加上领域事件,很可能造成遗漏。我们系统对此的解决方案是:将领域事件发送收敛到数据库上。业务操作,最终的效果是修改数据库,那么我们就监听相应数据库的binglog,发出相应的领域事件。
    这种解决方案可能会有以下问题:
    首先一个领域事件可能对应不只一张表的修改。为了不遗漏领域事件,我们不得不监听多张表。每个表修改时,我们都会发出领域事件,这就导致业务上同一个领域事件可能会重复发送。幂等操作只能交给接收方来做了。
    监听binlog发送领域事件带来的另一个改造问题是消息中各字段的准确性问题。正常发送领域事件时,在业务处理的过程中就能获取领域事件的各个字段。但一张表上可能不会有完整的领域事件信息,需要反查其他表进行字段填充。某一业务操作会修改t1,t2两张表,A,B两个业务操作前后发生。A操作导致的t1 binlog消息到达了,查询t2表上的字段,此时t2却已经被B操作修改了,则反查出来的结果是B操作后的数据结果。那么拼装消息时,部分字段是A导致的,部分字段是B导致的,就会组装出一个没有真实发生的领域事件,可能对接收方有影响,具体影响还需要接收方想办法化解。

  • 领域事件处理
    处理消息逃不开的三个问题:幂等,重试,丢失。真实写代码时有太多细节需要注意,只能case by case的看了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,377评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,390评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,967评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,344评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,441评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,492评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,497评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,274评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,732评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,008评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,184评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,837评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,520评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,156评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,407评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,056评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,074评论 2 352

推荐阅读更多精彩内容

  • 定义 将领域中所发生的活动建模成一系列的离散事件。每个事件都用领域对象来表示。领域事件是领域模型的组成部分,表示领...
    marx_yu阅读 1,729评论 0 0
  • 拆书稿 一、领域事件是什么? 定义:领域专家所关心的(需要跟踪的、希望被通知的、会引起其他模型对象改变状态的)发生...
    wiwisir阅读 320评论 0 0
  • 最近在换工作,利用间隙看了两本领域驱动设计的经典书籍:《领域驱动设计:软件核心复杂性应对之道》,《实现领域驱动设计...
    無式阅读 582评论 0 1
  • @大鹏开源:别看我有点萌,我可以秒变大鹏😄 DDD 与领域事件 在过去的 30 多年,就已经有领域建模和设计的思潮...
    StruggleYang阅读 7,387评论 0 3
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,532评论 28 53