开发者学堂课程【事件总线 EventBridge 生态集成课程: EventBridge EDA (事件驱动):架构场景实践】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/1235/detail/18407
EventBridge EDA (事件驱动):架构场景实践
4.什么是事件
下面再去了解一下什么是事件。给大家一个重点讲一下,有没有对 message 做分装,是事件和 message 本质的区别。在传统的 MNS Queue 架构里面,上游方和下游方说是结构,但并不是完全结构的。因为上游方把一个参数比如一个图片分装成一个 Base64,然后把图片直接塞到 data 里面。下游的接收方就应该知道这个信息,这个字段是什么,这个字段是一个图片,需要用 Base64 的方式把它给解开,这是消息的架构。会发现一个非常显著的问题,下游方必须和上游方做完全的 match,不然下游方根本不知道字段里面塞的是什么,可能是 Base64 字段,可能是一个文本,甚至可能是一个加密过的字段,如果 A 端和 B 端不是通过类似事件做标准化的的话,会发现它会有沟通不一致的问题,这个问题也是在实际生产过程中非常常见的,要不然不能跨部门沟通,成建部门一定要知道源端发送部门的一些类似信息,比如字段是什么意思,每个字段怎么定义,每个字段怎么去用,这是在 message 架构里面比较确定的一点,它并不是完整的,它是必须得通过文档或者其他方式把这些字段告知给下游接收方,下游接收方才有可能把 message 给用起来,这个其实是消息。
所以什么是事件驱动?事件驱动是对消息的上一层分装,分装是什么意思?即之前消息会发现没有办法解决 A 端到 B 端完结结构,因为不知道消息里面塞的到底是什么?那事件就做了这样的标准化,然后这个事件标准化其实是做类似于云原生 CF 基金会在2018年托管开源的项目叫 events 的项目,然后这个项目其实是制定了统一和规范的格式来描述事件。描述事件的本质目的是解决刚刚场景,是用来去加强不同服务,包括平台系统之间的一些操作性,包括刚刚所说的 case,可以把描述直接定义到事件里面。然后下游端直接看这个事件,就知道字段是什么意思,然后是用 XML 还是 jason?这个其实是事件。宏观上来定义事件,发现事件确实可以解决一些痛点,那事件到底是什么或者是什么情况下可以分享事件,这里打一个最简单的 case,以 4S 店售卖汽车为典型的 case,比如客户在购买汽车时候,把代售状态变为已售状态,它就是一个事件,因为它针对汽车的销售状态产生变更,这种变更就可以称之为一个事件。然后客户拿到车之后,把金额交付了,成功付款了,从账户中扣了一笔金额,扣除的过程,比如账单金额是从自身掏了一万块钱,这一万块钱划走了,这种情况也是一个事件,还有一个状态是在买汽车的时候,可能会有一些预定或者是试驾的操作,然后把一辆车的预定信息附加给一个用户,这种也是会被称为事件。
所以可以归纳一下事件是什么,其实就是当在某一时刻,当某个东西发生状态变更的时候,都可以把它称之为事件变更。每个事件都可以触发一个或多个选项,作为响应,这句话理解起来,意思是比如我的汽车从待售变成已售,状态变更需要干几件事,第一是通知客户,买到车了,这个车归你了,这个是客户车,第二个需要在存储系统里面,把订单的车辆号剔掉,代表这个车已经售出了,这也是一个事件。所以每个事件都可以被多个接收方响应,是这样的意思。
然后右侧是现在 events 定义的标准的事件范式,比如它会有几个字段,比如 specversion, 它是版本号遵循的 events 的多少版本,现在最新的是0.2,没有版本更新,现在还是一点差的阶段。Type 定义类型,source 定义事件发送端,source到底是哪方发送的?以汽车为例,发布端是提交系统的端,source 是可以自定义的,只要规范好就可以,然后 subject 其实是对 source 的详细的解释,包括 I D、time,包括下面的那些拓展字段,都是对现有的字段的解释或者阐述,要把待售变成已售状态,这些字段从哪写呢?其实在data。它后面会有一个 data 字段,所以 data 字段其实是所有数据主体,前面可以理解为它是一个大信息或者云数据,它会把一些比较关键的信息给它放到头部,解释这个事件怎么用、被谁用、用的方式是怎样的?这个是对从 message 到事件的升级或者分装。PPT 主要做了一件事情,讲清楚了什么是事件。
三、事件驱动架构设计
1.一个简单的 EDA 架构
给大家简单讲一下 case,或者业内比较完善的架构范式。帮助大家理解事件驱动架构在实际应用产品中怎么使用或有哪些比较经典的使用 case。
第一个比较简单,大家都能看出来,和第一个订单系统如出一辙,只不过它换了一个词叫 HR 系统,然后 HR 系统这个产品先来给大家梳理一下,HR 系统为什么会用到 EDA 架构?因为在 HR 系统中,通常会有一些情况。比如有个新员工要入职,那作为一个企业来讲,一个新员工入职,他要干很多事情。
第一个事情就是最典型的,要去发欢迎邮件,可能会在团队内或者是组织内发一个欢迎邮件,把这个人的基本信息告诉大家,这个人他名字是什么,他是哪个学校毕业的,他的兴趣爱好是什么,类似的这种欢迎邮件。这个是需要用 HR 系统做的一些事情。
第二个是 Queue。什么是 Queue?比如系统可能自研了人员管理或其他一些系统或者是要把人员管理同步到其他部门,可能同步到财务或者同步到其他一些部门,其它部门会有自己的一些系统。这个对接可能用的是 message 的对接。需要去上游把某一些特定信息写到下游的 message 里面。HR 系统和财务或者其他系统,或者是集团其他的一些分部门做沟通。
第三是需要对现有的人员库进行更新,比如 HR 系统的底层。底层是数据库或者叫做离线存储的数据。要把人员信息入库,或者把信息做一些变更,比如人员之前在预备人才库里,然后他入职了,变成在职人员了,需要把它状态变更一下,这种操作叫更新,即 record。这是现在简单的 EDA 架构模型,它特别简单。它利用的是 HR 系统操作节点可能是人员。然后 HR 决定要录用某个人了,给你发了份 offer,然后已经入职了,把状态变更,分装成一个事件。这些事件投递到某一个总线上面,或者是 broker 上面,通过 broker 分发到下游端,或者通过eventbus分发到下游端。比如邮件发到 MNS Queue 跟其他系统对接,要更新自己数据库状态,这是简单的 EDA 架构。后面会围绕这个简单的 EDA 架构给大家演示一下在 eventbridge 产品里面怎么把架构落地和实现。
2. Serverless + EDA 云原生架构
下面是非常经典的 Severless + EDA 云原生架构体系,这个体系下串了好多产品。这个系统是比较典型的订单推送流程。这个系统的中间节点是 eventbridge。Eventbridge 可以做分发、过滤和转换。可以把列表给梳理一下。
首先,发送一个订单,去下一个单,单可能下到 API 网关上面,然后 API 网关把订单信息然后发到一个函数计算,然后这个函数计算会把这些事件做一些分装,投递到 event bridge。然后函数计算给大家解释一下。假如大家不太了解它,可以把函数计算想象成容器里的 note,或者服务节点、服务载体。推荐直接使用 FC 做这样操作。FC 直接到 event bridge,Event bridge 第一件事情是把订单分发,把订单下发调到另一个 FC 上面,即另一个服务节点上面。通过下游的 FC 把这个订单推到 MQ,MQ做一些处理,到购物车配送到用户侧,这是主链路。
第二条链路干什么呢?第二条链路把这条事件,把订单通知下发到了一个通知服务里面。然后这个通知服务是推送一些确认信息,同样把确认信息下发给用户。发现有两个分节点,第一个分节点在通知。假如短信通知成功后,把通知成功的状态告诉 EB,EB 再去做一些下游的处理。比如回置,做一些系统订单。还会把订单状态的一些信息再次推给 EB,然后 EB 再去做过滤和处理,然后把这种东西告诉用户,比如订单状态从待配送变成已配送,这是变更,发到 EB 上,EB 接到通知后,调用通知能力,告诉客户订单已经开始配送了。
还有一个系统是订单确认系统。网关会生成事件,会有确认订单的操作,同样也调用 EB,然后 EB 调用通知能力,通知给用户。或者订单被确认推送了,已经完成了订单,同样还是可以调用 EB,通过 EB 往下去推。这个图看起来复杂,但其实想从图里告诉大家 EDA 它本身来讲是必须要有一些过滤筛选,包括重复推送的一些能力。它需要做中间的枢纽化操作。EDA 一定会有一些消息过滤,可以过某些规则去感知的。某些事件,这个事件是成功事件还是失败事件,这些事件是需要去推送下游的某个端。所以 eventbridge 即中间节点一定具备过滤和分发的能力。而且这个能力一定得非常强悍,才可以把云原生的 EDA 架构体系给它落地。这是 EDA 架构模型最终延伸的版本。EDA 不只能往下推送,可以做复杂地逻辑分发,推送转储包括交付下游的一些复杂逻辑。这是重点想给大家讲解地方。
讲完了 serverless + eda 云原生架构。第一个观点是这个中间节点一定要得足够强大,作为中间节点来讲,基本上所有事情都会经过中间节点进行分发。第二个观点就是这个中间节点一定要有分析转发特定事件的能力,就是说这个事件不是说所有的东西都往下分发,而是说会挑部分事件或者是会挑单个来配送。第三个观点是 EDA 不只是单向的往下游分发,同样它也可以去做回调,发邮件之后知道这个邮件没有成功,一样可以以相同的状态再去发给 eb,Eb 再去做后续处理。