共计 7097 个字符,预计需要花费 18 分钟才能阅读完成。
前言
事件驱动,这个词在局部人印象中,它是一个过期的技术——没什么新意。从工夫上看,的确也是这样,上世纪 60 年代,事件驱动就曾经被正式提出,常常会被利用在 GUI 编程中。然而在有些人印象中,事件驱动又是一个十分生疏,十分新鲜的技术。
不论怎么样,事实是曾经有越来越多的公司,开始或则经把事件驱动架构利用到企业的外围业务中,包含:阿里巴巴、喜力、联合利华、美国联邦航空管理局、银行资本市场等等。市场上,也有很多公司推出了本人的产品或解决方案,比方阿里云、AWS、Google,Solace。行业里也孕育出了事件的规范:CloudEvents。Gartener,则把事件驱动定义为将来十大趋势之一。
这个时候,咱们就要问了,事件驱动架构到底是什么呢?为什么当初被越来越多的人,开始关注事件驱动架构了呢?
5 月 28 日,GOTC 2023 寰球开源技术峰会上,阿里云智能技术专家沈林发表主题演讲:Apache RocketMQ 事件驱动引擎。
$$
阿里云智能技术专家:沈林
$$
什么是事件?
说到事件驱动架构,大家第一印象往往会把重点放在“架构”这两个字上,然而,事件驱动架构很大的魅力其实来源于后面“事件”两个字,所以明天,咱们先一起看下什么是事件。RocketMQ 之前始终给人的印象是一个音讯引擎,那为什么咱们在前段时间公布的 5.0 版本中,引入了事件?音讯跟事件,又有什么区别呢?
事件,如果咱们查阅字典,他会给你这样一个解释:事件是指过来曾经产生的事,尤其是比拟重要的事。
这个很好了解啊。比方,GOTC 大会明天在上海正式揭幕了;方才我的手机铃声响了;这些都是过来曾经产生的事件。
然而,如果咱们接着方才的问题问:事件跟音讯有什么区别呢?这个时候,大家是不是感觉事件这个定义,如同又不那么清晰了?方才咱们说的那些事件,是不是也能够了解为音讯?如果这个时候,老张给我发送了一条短信,那这个短信,算是事件,还是音讯呢?
咱们能够通过这张图,来简略了解音讯和事件的关系。音讯蕴含两类,一类是 Command 音讯,另一类就是 Event 音讯。
1、Command 音讯是什么?咱们看上面右边这张图,内部零碎发送给本零碎的一条操作命令,就是 Command 音讯;
2、那什么是 Event 音讯呢?再看上面左边这张图,本零碎收到内部 Command 操作申请,零碎外部产生扭转之后,就产生了 Event;
所以,事件和音讯略微有些不同。事件,能够了解为是一种非凡的音讯,那事件非凡在什么中央呢?次要蕴含 4 个方面:
事件的个性 1:已产生且不可变的
事件,肯定是“已发的”。“已产生”的代表什么呢?不可变的。咱们不可能扭转过来,除非你有超能力。这个个性十分重要,在咱们处理事件、剖析事件的时候,这就意味着,咱们相对能够置信这些事件,只有是收到的事件,肯定是零碎实在产生过的行为,而且是 Immutable,不可批改。
比照 Command 音讯,Command 的中文是什么?命令!很显然,它还是没有产生的,而是表白了一种冀望。咱们晓得,“冀望的”不肯定会胜利产生。比方:
- 把厨房的灯关上;
- 去按下门铃;
- 转给 A 账户 10w;
这些都是 Commond,都是冀望产生的行为。然而,最终有没有产生呢?并不知道。
Event 则是明确曾经产生的事件。比方:
- 厨房灯被关上了;
- 有人按了门铃;
- A 账户收到了 10w
事件的个性 2:无冀望的
事件的第二个个性是:无冀望的。事件是主观的形容一个事物的状态或属性值的变动,但对于如何处理事件自身并没有做任何冀望。相比之下,Commond 则是有冀望的,它心愿零碎做出扭转;然而 Event,它只是主观形容零碎的一个变动。咱们举一个例子:交通信号灯从绿灯变成红灯,它就是一个事件。事件自身并没有任何冀望,说要求行人或汽车禁止通行,而是交通法规须要红绿灯,并赋予了其规定。
所以,零碎,个别不会定向的、独自向一个指定的零碎发送事件,而是对立的通知“事件核心”。“事件核心”那外面有各个系统上报上来的,各式各样的事件。零碎会向事件核心阐明:本人这个零碎,会产生哪些事件,这些事件的格局是怎么样的;别的零碎如果感兴趣,就能够来被动订阅这些事件;真正赋予事件价值的,是事件消费者。事件消费者想看看,某个零碎产生了什么变动?OK,那他就去订阅这些事件,所以事件是消费者驱动的。
这跟音讯有什么区别呢?Commond 音讯的发送和订阅,是单方约定好的,外人不晓得,往往是以文档或代码的模式,大家按约定好的协定,发送和订阅生产,这个过程往往是生产者驱动的。
打个比喻,事件就像市场经济,商品被生产进去,具体有什么价值,有多大价值,很大水平上看其消费者。咱们能看到零碎中各种各样的事件,就像橱窗里摆放了各种各样的商品;而 Commond 音讯,有点像计划经济,一出世就带着很强的目的性,“我”就是要“调配”给谁生产。
事件的个性 3:人造有序且惟一的
事件的第三个个性是:“人造有序且惟一的”。同一个实体,不能同时产生 A 又产生 B,必有先后关系;如果是,则这两个事件必属于不同的事件类型。仔细的同学,必定发现了一点,这里其实暗藏了事件的一个额定属性:因为人造有序,跟时间轴上的某一时刻强绑定,且不能同时产生,所以它肯定是惟一的。
如果咱们看到了两个内容一样的事件,那么肯定是产生了两次,而且一次在前,一次在后。这对于咱们解决数据最终一致性、以及零碎行为剖析都很有价值:咱们看到的,不光是零碎的一个最终后果,而是看到变成这个后果之前的,一系列两头过程。
事件的个性 4:具象化
事件的第四个个性是:“具象化”。事件会尽可能的把“案发现场”残缺的记录下来,因为它也不晓得消费者会如何应用它,所以它会做到尽量的详尽,包含:什么时候产生?是由谁产生的事件?是什么类型的事件?是谁发送的事件?事件的唯一性标记是什么?事件的内容是什么?等等。
再比照咱们常见的音讯,因为上下游个别是确定的,经常为了性能和传输效率,则会做到尽可能的精简,只有满足“计划经济”指定安顿的消费者需要即可。
什么是事件驱动架构?
讲完事件,咱们再回过头来,一起看看,什么是事件驱动架构。为了不便了解,咱们举一个简略的例子:咱们都晓得:交易系统在实现订单交易之后,有很多零碎都“须要”晓得这个订单信息,比方:
- 物流零碎,须要晓得这个订单信息,来安顿发货;
- 积分零碎,须要晓得这个订单信息,来从新计算这个用户的积分;
- 营销零碎,须要晓得这个订单信息,来计算当天的实时交易额。
这里咱们有三种形式来实现上游交易系统和上游物流、积分、营销零碎的集成。
上下游集成
形式 1:被动调用
一种最简略的实现形式是:交易系统顺次调用每个零碎,把订单信息收回去。比方下图这种形式:
但咱们都晓得,这个设计,是十分蹩脚。尤其当越来越多的零碎加进来时,不仅开发成本高,而且万一其中一个零碎呈现问题,解决不好,很容易影响其余零碎的发送。
形式 2:音讯异步解耦
一个很天然的解决方案是:咱们将订单信息,发送到两头的一个音讯 broker 服务。而后,物流零碎、积分零碎、营销零碎只须要去订阅 Broker 的这些交易订单音讯就能够了,非常简单清晰。
形式 3:事件驱动架构
那如果是在事件驱动架构中,应该怎么做呢?交易系统,依旧会将交易订单发送到咱们两头的 Broker 服务,然而上游服务不再须要被动订阅 Broker 中的交易订单,而往往是 Broker 推送给上游零碎。这个时候,大家可能既有疑难了,这个如同跟形式 2 音讯异步解耦,没有太大的区别吧?难道事件驱动架构,就是简略的把 Pull 模式变成了 Push 模式?
这里咱们围绕上游和上游,看看事件驱动架构带来了什么扭转。
面向上游
1、耦合的收缩
这里咱们衍生一下,很多时候,上游的营销零碎它不是只依赖一个交易系统产生的订单数据,比方:它可能同时须要淘宝的交易订单、京东的交易订单、拼多多的交易订单,来实时计算一个以后时刻汇总值。这个时候,在“音讯异步解偶”的架构中,客户的营销零碎须要做两件事:
第一,订阅三个 Broker 服务,来获取淘宝、京东、拼多多的交易订单数据;
第二,因为淘宝、京东、拼多多的交易订单数据格式,是不同的,所以客户的营销零碎,须要对三种数据格式进行适配,先转换成营销零碎外部冀望的数据格式,而后再解决。
而且,如果前面客户又在抖音开店,客户的营销零碎须要再适配一遍;如果某家的订单数据格式发生变化,那客户营销额零碎也必须联动的进行更新。
如果在事件驱动架构中,客户的营销零碎,须要怎么做呢?他什么都不须要,只有登高一声大喊:“我须要什么样的订单事件格局,我提供一个 API,其余零碎就按这个订单事件格局发给我就能够了”。EventBroker 会将上游的事件转换成客户营销零碎须要的数据格式,发送给他的 API。不论接多少零碎的交易订单、不论内部零碎怎么变,反正我不变。
2、耦合方向
这里咱们剖析下这三种形式的耦合关系:咱们要晓得,耦合是有方向性的。
- 形式 1- 间接调用: 是上游 A 依赖上游 B;(一旦上游 B 产生扭转,A 须要同步的扭转)
- 形式 2- 音讯异步解偶:是 B 依赖于 A;(一旦上游 A 的数据格式,产生扭转,B 须要同步的扭转)
- 形式 3- 事件驱动:A 不依赖于 B,B 也不依赖于 A;(所有的耦合,都由两头的 Event Broker 来对立解决和保护)
3、影响零碎稳固的因子有哪些?
除了升高依赖,上游零碎在开发的时候,最关注的是什么?对大部分业务场景来说,最重要的是:开发保护成本低、稳固又牢靠。不过,在音讯异步解偶架构中,大家有没有发现,影响以后上游这个零碎发生变化的入口,是不是有两个?(就是上面咖啡色的局部) 一个是 API;一个是音讯订阅。
一个零碎,有两个入口会引起发生变化,是一件十分麻烦的事。这意味着:咱们在开发和保护这个零碎的稳定性时,须要守护好两个口子:无论是身份认证、审计、平安、流控、测试、保护等等,咱们都要两边思考。不仅老本高,而且很容易出问题。
4、可测试性和可维护性
在事件驱动架构模式中,上游零碎只须要提供一个 API 入口。
- 对外:这个 API,既是用来接管上游的事件,也能够用来和其余零碎间的通信;
- 对内:这个 API 的设计,是围绕上游零碎以后本人的畛域模型去设计的,不须要去适配任何其余零碎;
所以整个零碎,会十分简洁。简洁的益处是:当咱们须要变更零碎时,只须要保障咱们提供的 API 牢靠,可测试性和可维护性都大大晋升。
5、Serverless
事件驱动还有一个十分大的劣势是能够通过事件的形式,按量驱动 Serverless,去进行生产。还是在咱们交易订单这个场景下:
- 有些小商家的的订单量其实没有那么多,那独自部署一个积分零碎服务,7*24 小时始终跑着,是很节约的一种行为。这个时候,如果通过事件驱动模式:当只有交易订单事件产生时,才去触发上游 Serverless 服务,按量计算付费,可能极大的升高咱们的老本;
- 而对有些商家,交易订单量十分大,尤其是遇到节日大促的时候,流量峰值会十分高,这个时候,如果通过事件驱动模式,按量触发 Serverless 进行计算,可能更好的晋升零碎的解决能力的峰值;
- 另外,如果上游零碎会因为某些异样事件,影响零碎稳定性。那通过事件驱动触发 Serverless 的形式,人造的就能够提供很好的隔离性,并实现疾速复原;
Serverless 曾经逐渐成为云原生时代,一股势不可挡的趋势,而事件驱动和 Serverless 则是一对最好的兄弟组合。
面向上游
SaaS 集成
下面都是围绕上游开展,那对于上游零碎来讲,事件驱动的意义在哪呢?咱们想一下,对上游零碎来讲,它最关怀的是什么?它关怀的必定不是零碎的稳定性和解耦这些货色,不是说这些货色不重要,而是对上游零碎来讲,发送到音讯 Broker,和事件 Broker 没什么区别。那什么对上游零碎来说是最重要的呢?这里实质上是,上游零碎心愿能够和更多的零碎实现集成,来打造本人的生态位。
这个怎么了解呢?咱们举一个例子:门禁打卡零碎。
门禁打卡零碎,卖给不同的公司,须要反对员工打卡的记录信息同步到不同公司的 ERP 零碎中,这个时候,如果门禁打卡零碎本人 One By One 去集成适配各个公司的 ERP 零碎,老本是十分高的,简直不事实;如果不去集成,可能很多公司可能就不买你的了。
所以,对于上游零碎来说,可能省心省力的与生态内的产品不便集成,是最重要的事件。而在事件驱动架构模式中,门禁打卡零碎只须要以事件的模式,把员工打卡事件记录下来,交给事件核心,剩下的事件就不必操心了。事件核心会对立负责上游生态的集成对接。
另外,对于门禁打卡零碎自身,它也须要晓得新员工的入职事件,因为只有这样,在新员工打卡的时候,才可能及时辨认。如果通过事件驱动模式,门禁打卡零碎就能够轻松的在 SaaS 生态中,从零开始,疾速打造本人的生态位。
如何做一个优良的事件驱动引擎
后面讲了这么多,理解了什么是事件以及什么是事件驱动架构。也理解到事件驱动架构独特的一些魅力:为什么事件驱动架构,被越来越多的公司喜爱。
最初,咱们讲一下,如果要做一个优良的事件驱动引擎,须要具备哪些能力?咱们 RocketMQ EventBridge 怎么做的?
须要什么样的能力?
第一,咱们必定得有一个事件规范。因为事件不是给本人看的,也不是给他看的,而是给所有人看的。事件没有明确的消费者,所有都是潜在的消费者,咱们得规范化事件的定义,让所有人都能看得懂,高深莫测;
第二,咱们得有一个事件核心,事件中心里有所有零碎注册上来的各种事件。这个有点相似市场经济大卖场,玲琅满目,外面分类摆放了各种各样的事件,所有人即便不买,也都能够进来瞧一瞧,看一看,有哪些事件,可能是我须要的,那就能够买回去;
第三,咱们得有一个事件格局,用来形容事件的具体内容。这相当于市场经济的一个交易契约。生产者发送的事件格局是什么,得确定下来,不能总是变;消费者以什么格局接管事件也得确定下来,不然整个市场就乱套了;
第四,咱们得给消费者一个,把投递事件到指标端的能力,并且投递前,能够对事件进行过滤和转换,让它能够适配指标端 API 接管参数的格局,咱们把这个过程对立叫做订阅规定。
第五,咱们还得有一个存储事件的中央,就是最两头的事件总线。
如何形容事件
对于方才提到的第一点事件规范,这个很重要。事件规范,就相当于不同零碎之间交换的语言,如果语言都不通,互相交换必定会出很多问题。咱们举荐应用 CNCF 旗下的开源 CloudEvents 协定,目前曾经很多公司宽泛集成,算是一个事实上的规范。CloudEvent 协定也很简略,咱们有一个简略的例子, 具体能够参考官网 [1]:
{
"specversion":"1.0",
"type":"com.github.pull_request.opened",
"source":"https://github.com/cloudevents",
"subject":"123",
"id":"A234-1234-1234",
"time":"2018-04-05T17:31:00Z",
"comexampleextension1":"value",
"comexampleothervalue":5,
"datacontenttype":"text/xml",
"data":"<much wow=\"xml\"/>"
}
事件核心
另外,咱们必须得有一个事件核心。事件核心对于事件驱动架构来说,是十分重要的一个角色。他就像咱们方才说的市场经济的大卖场,所有的事件,在这个大卖场里,都有具体的应用阐明,大家都能够进来瞧一瞧,看一看,感觉适合,就订阅买走。
至于事件核心如何治理,咱们能够从 API 治理里学习很多教训:咱们晓得 API 蕴含注册、Schema 形容、Sample、文档、SDK、测试、监控。Event,其实也是一样,它须要在事件核心被注册,定义 Schema 形容、Sample、文档、CodeBinding、测试、监控。
这样消费者拿到这个事件的时候,才晓得是什么,怎么用,用的释怀。
Schema
事件的 Schema,是用来形容事件中有哪些属性、含意等等信息。为什么咱们要引入 Schema?一方面是,为了让上游可能了解事件的格局,方便使用事件;另一方面,也是为了限度上游发送事件的格局,发送和批改都必须保障兼容,一旦契约签订,不能轻易批改。咱们举荐应用 Json Schema 和 OpenAPI 3.0。
事件过滤和转换
对于事件的过滤和转换,RocketMQ 事件驱动引擎 提供了丰盛的事件过滤和转换形式。这些我就不具体一一开展了,具体大家能够上图形容。
RocketMQEventBridge 技术架构
最初,咱们 RocketMQ 围绕事件驱动推出的产品,叫做 EventBridge,他的整个架构能够分为两局部:下面是咱们的管制面、上面是咱们的数据面。
管制面:面向上游,做好事件的治理。通过 EventSource,把上游产生的事件,治理起来,让大家找失去须要的事件,找到事件后,晓得怎么用;面向上游,能够通过 EventRule,让消费者,不便的把事件转换成须要的格局,并推送给本人。
两头的 EventBus,是咱们存储事件的中央,底下应用的是咱们 RocketMQ 本人的 Broker;
数据面:是事件的通道,咱们除了能够通过 API 发送事件到 EventBus 之外,还能够通过 Source Connector 被动拉事件到 EventBus。消费者创立 EventRule 之后,则能够通过 Sink Connector 将事件,推送到指标端;
除此之外,咱们还会有:事件追踪、事件回放、事件剖析、事件归档等等。
点击立刻收费试用云产品 开启云上实际之旅!
原文链接
本文为阿里云原创内容,未经容许不得转载。