Apache RocketMQ EventBridge,构建下一代事件驱动引擎

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
可观测可视化 Grafana 版,10个用户账号 1个月
简介: 本文主要介绍了事件以及特性,优秀的事件驱动引擎,需要具备的能力以及Apache RocketMQ EventBridge是如何做的。

1.前言


事件驱动,这个词在部分人印象中,它是一个过时的技术——没什么新意。从时间上看,确实也是这样,上世纪 60 年代,事件驱动就已经被正式提出,经常会被应用在 GUI 编程中。但是在有些人印象中,事件驱动又是一个非常陌生,非常新颖的技术。


不管怎么样,现实是已经有越来越多的公司,开始或则经把事件驱动架构应用到企业的核心业务中,包括:阿里巴巴、喜力、联合利华、美国联邦航空管理局、银行资本市场等等。市场上,也有很多公司推出了自己的产品或解决方案,比如阿里云、AWS、Google,Solace。行业里也孕育出了事件的标准:CloudEvents。Gartener,则把事件驱动定义为未来十大趋势之一。


这个时候,我们就要问了,事件驱动架构到底是什么呢?为什么现在被越来越多的人,开始关注事件驱动架构了呢?



2023年 5 月 28 日,GOTC 2023 全球开源技术峰会上,阿里云智能技术专家沈林发表主题演讲:Apache RocketMQ 事件驱动引擎。

image.png

Apache RocketMQ PMC&阿里云智能技术专家:沈林


2.什么是事件?


说到事件驱动架构,大家第一印象往往会把重点放在“架构”这两个字上,但是,事件驱动架构很大的魅力其实来源于前面“事件”两个字,所以今天,我们先一起看下什么是事件。RocketMQ 之前一直给人的印象是一个消息引擎,那为什么我们在前段时间发布的 5.0 版本中,引入了事件?消息跟事件,又有什么区别呢?


事件,如果我们查阅字典,他会给你这样一个解释:事件是指过去已经发生的事,尤其是比较重要的事。


这个很好理解啊。比如,GOTC 大会今天在上海正式开幕了;刚才我的手机铃声响了;这些都是过去已经发生的事件。


但是,如果我们接着刚才的问题问:事件跟消息有什么区别呢?这个时候,大家是不是觉得事件这个定义,好像又不那么清晰了?刚才我们说的那些事件,是不是也可以理解为消息?如果这个时候,老张给我发送了一条短信,那这个短信,算是事件,还是消息呢?


我们可以通过这张图,来简单理解消息和事件的关系。消息包含两类,一类是 Command 消息,另一类就是 Event 消息。


1、Command 消息是什么?我们看下面左边这张图,外部系统发送给本系统的一条操作命令,就是Command消息;


2、那什么是 Event 消息呢?再看下面右边这张图,本系统收到外部 Command 操作请求,系统内部发生改变之后,就产生了 Event;


所以,事件和消息稍微有些不同。事件,可以理解为是一种特殊的消息,那事件特殊在什么地方呢?主要包含 4 个方面:

image.png

2.1事件的特性 1:已发生且不可变的

事件,一定是“已发的”。“已发生”的代表什么呢?不可变的。我们不可能改变过去,除非你有超能力。这个特性非常重要,在我们处理事件、分析事件的时候,这就意味着,我们绝对可以相信这些事件,只要是收到的事件,一定是系统真实发生过的行为,而且是 Immutable,不可修改。


对比 Command 消息,Command 的中文是什么?命令!很显然,它还是没有发生的,而是表达了一种期望。我们知道,“期望的”不一定会成功发生。比如:


  • 把厨房的灯打开;
  • 去按下门铃;
  • 转给 A 账户 10w;


这些都是 Commond,都是期望发生的行为。但是,最终有没有发生呢?并不知道。

Event 则是明确已经发生的事情。比如:


  • 厨房灯被打开了;
  • 有人按了门铃;
  • A 账户收到了 10w


2.2事件的特性 2:无期望的

事件的第二个特性是:无期望的。事件是客观的描述一个事物的状态或属性值的变化,但对于如何处理事件本身并没有做任何期望。相比之下,Commond 则是有期望的,它希望系统做出改变;但是 Event,它只是客观描述系统的一个变化。我们举一个例子:交通信号灯从绿灯变成红灯,它就是一个事件。事件本身并没有任何期望,说要求行人或汽车禁止通行,而是交通法规需要红绿灯,并赋予了其规则。


所以,系统,一般不会定向的、单独向一个指定的系统发送事件,而是统一的告诉“事件中心”。“事件中心”那里面有各个系统上报上来的,各式各样的事件。系统会向事件中心说明:自己这个系统,会产生哪些事件,这些事件的格式是怎么样的;别的系统如果感兴趣,就可以来主动订阅这些事件;真正赋予事件价值的,是事件消费者。事件消费者想看看,某个系统发生了什么变化?OK,那他就去订阅这些事件,所以事件是消费者驱动的。


这跟消息有什么区别呢?Commond 消息的发送和订阅,是双方约定好的,外人不知道,往往是以文档或代码的形式,大家按约定好的协议,发送和订阅消费,这个过程往往是生产者驱动的。


打个比喻,事件就像市场经济,商品被生产出来,具体有什么价值,有多大价值,很大程度上看其消费者。我们能看到系统中各种各样的事件,就像橱窗里摆放了各种各样的商品;而 Commond 消息,有点像计划经济,一出生就带着很强的目的性,“我”就是要“分配”给谁消费。


2.3事件的特性 3:天然有序且唯一的

事件的第三个特性是:“天然有序且唯一的”。同一个实体,不能同时发生 A 又发生 B,必有先后关系;如果是,则这两个事件必属于不同的事件类型。细心的同学,肯定发现了一点,这里其实隐藏了事件的一个额外属性:因为天然有序,跟时间轴上的某一时刻强绑定,且不能同时发生,所以它一定是唯一的。


如果我们看到了两个内容一样的事件,那么一定是发生了两次,而且一次在前,一次在后。这对于我们处理数据最终一致性、以及系统行为分析都很有价值:我们看到的,不光是系统的一个最终结果,而是看到变成这个结果之前的,一系列中间过程。


2.4事件的特性 4:具象化

事件的第四个特性是:“具象化”。事件会尽可能的把“案发现场”完整的记录下来,因为它也不知道消费者会如何使用它,所以它会做到尽量的详尽,包括:什么时候发生?是由谁产生的事件?是什么类型的事件?是谁发送的事件?事件的唯一性标志是什么?事件的内容是什么?等等。


再对比我们常见的消息,因为上下游一般是确定的,常常为了性能和传输效率,则会做到尽可能的精简,只要满足“计划经济”指定安排的消费者需求即可。


3.什么是事件驱动架构?


讲完事件,我们再回过头来,一起看看,什么是事件驱动架构。为了方便理解,我们举一个简单的例子:我们都知道:交易系统在完成订单交易之后,有很多系统都“需要”知道这个订单信息,比如:


  • 物流系统,需要知道这个订单信息,来安排发货;
  • 积分系统,需要知道这个订单信息,来重新计算这个用户的积分;
  • 营销系统,需要知道这个订单信息,来计算当天的实时交易额。


这里我们有三种方式来实现上游交易系统和下游物流、积分、营销系统的集成。


3.1上下游集成

方式 1:主动调用

一种最简单的实现方式是:交易系统依次调用每个系统,把订单信息发出去。比如下图这种方式:

image.png

但我们都知道,这个设计,是非常糟糕。尤其当越来越多的系统加进来时,不仅开发成本高,而且万一其中一个系统出现问题,处理不好,很容易影响其他系统的发送。


方式 2:消息异步解耦

一个很自然的解决方案是:我们将订单信息,发送到中间的一个消息 broker 服务。然后,物流系统、积分系统、营销系统只需要去订阅 Broker 的这些交易订单消息就可以了,非常简单清晰。

image.png

方式 3:事件驱动架构

那如果是在事件驱动架构中,应该怎么做呢?交易系统,依旧会将交易订单发送到我们中间的 Broker 服务,但是下游服务不再需要主动订阅 Broker 中的交易订单,而往往是 Broker 推送给下游系统。这个时候,大家可能既有疑问了,这个好像跟方式 2 消息异步解耦,没有太大的区别吧?难道事件驱动架构,就是简单的把 Pull 模式变成了 Push 模式?

image.png

这里我们围绕上游和下游,看看事件驱动架构带来了什么改变。


3.2面向下游

1、耦合的膨胀

这里我们衍生一下,很多时候,下游的营销系统它不是只依赖一个交易系统产生的订单数据,比如:它可能同时需要淘宝的交易订单、京东的交易订单、拼多多的交易订单,来实时计算一个当前时刻汇总值。这个时候,在“消息异步解偶” 的架构中,客户的营销系统需要做两件事:


第一,订阅三个 Broker 服务,来获取淘宝、京东、拼多多的交易订单数据;


第二,由于淘宝、京东、拼多多的交易订单数据格式,是不同的,所以客户的营销系统,需要对三种数据格式进行适配,先转换成营销系统内部期望的数据格式,然后再处理。


而且,如果后面客户又在抖音开店,客户的营销系统需要再适配一遍;如果某家的订单数据格式发生变化,那客户营销额系统也必须联动的进行更新。



如果在事件驱动架构中,客户的营销系统,需要怎么做呢?他什么都不需要,只要登高一声大喊:“我需要什么样的订单事件格式,我提供一个 API,其他系统就按这个订单事件格式发给我就可以了”。EventBroker 会将上游的事件转换成客户营销系统需要的数据格式,发送给他的 API。不管接多少系统的交易订单、不管外部系统怎么变,反正我不变。



2、耦合方向

这里我们分析下这三种方式的耦合关系:我们要知道,耦合是有方向性的。


  • 方式 1-直接调用:是上游 A 依赖下游 B;(一旦下游 B 发生改变,A 需要同步的改变)
  • 方式 2-消息异步解偶:是 B 依赖于 A;(一旦上游 A 的数据格式,发生改变,B 需要同步的改变)
  • 方式 3-事件驱动:A 不依赖于 B,B 也不依赖于 A;(所有的耦合,都由中间的 Event Broker 来统一处理和维护)


image.png


3、影响系统稳定的因子有哪些?

除了降低依赖,下游系统在开发的时候,最关注的是什么?对大部分业务场景来说,最重要的是:开发维护成本低、稳定又可靠。不过,在消息异步解偶架构中,大家有没有发现,影响当前下游这个系统发生变化的入口,是不是有两个?(就是下面咖啡色的部分) 一个是 API;一个是消息订阅。


一个系统,有两个入口会引起发生变化,是一件非常麻烦的事。这意味着:我们在开发和维护这个系统的稳定性时,需要守护好两个口子:无论是身份认证、审计、安全、流控、测试、维护等等,我们都要两边考虑。不仅成本高,而且很容易出问题。


image.png


4、可测试性和可维护性

在事件驱动架构模式中,下游系统只需要提供一个 API 入口。


  • 对外:这个 API,既是用来接收上游的事件,也可以用来和其他系统间的通讯;
  • 对内:这个 API 的设计,是围绕下游系统当前自己的领域模型去设计的,不需要去适配任何其他系统;


所以整个系统,会非常简约。简约的好处是:当我们需要变更系统时,只需要保障我们提供的 API 可靠,可测试性和可维护性都大大提升。


image.png


5、Serverless

事件驱动还有一个非常大的优势是可以通过事件的方式,按量驱动 Serverless,去进行消费。还是在我们交易订单这个场景下:


  • 有些小商家的的订单量其实没有那么多,那单独部署一个积分系统服务,7*24 小时一直跑着,是很浪费的一种行为。这个时候,如果通过事件驱动模式:当只有交易订单事件产生时,才去触发下游 Serverless 服务,按量计算付费,能够极大的降低我们的成本;
  • 而对有些商家,交易订单量非常大,尤其是遇到节日大促的时候,流量峰值会非常高,这个时候,如果通过事件驱动模式,按量触发 Serverless 进行计算,能够更好的提升系统的处理能力的峰值;
  • 另外,如果下游系统会因为某些异常事件,影响系统稳定性。那通过事件驱动触发 Serverless 的方式,天然的就可以提供很好的隔离性,并实现快速恢复;


Serverless 已经逐步成为云原生时代,一股势不可挡的趋势,而事件驱动和 Serverless 则是一对最好的兄弟组合。



3.3面向上游

SaaS 集成

上面都是围绕下游展开,那对于上游系统来讲,事件驱动的意义在哪呢?我们想一下,对上游系统来讲,它最关心的是什么?它关心的肯定不是系统的稳定性和解耦这些东西,不是说这些东西不重要,而是对上游系统来讲,发送到消息 Broker,和事件 Broker 没什么区别。那什么对上游系统来说是最重要的呢?这里本质上是,上游系统希望可以和更多的系统实现集成,来打造自己的生态位。


这个怎么理解呢?我们举一个例子:门禁打卡系统。


门禁打卡系统,卖给不同的公司,需要支持员工打卡的记录信息同步到不同公司的 ERP 系统中,这个时候,如果门禁打卡系统自己 One By One 去集成适配各个公司的 ERP 系统,成本是非常高的,几乎不现实;如果不去集成,可能很多公司可能就不买你的了。


所以,对于上游系统来说,能够省心省力的与生态内的产品方便集成,是最重要的事情。而在事件驱动架构模式中,门禁打卡系统只需要以事件的形式,把员工打卡事件记录下来,交给事件中心,剩下的事情就不用操心了。事件中心会统一负责下游生态的集成对接。



另外,对于门禁打卡系统本身,它也需要知道新员工的入职事件,因为只有这样,在新员工打卡的时候,才能够及时识别。如果通过事件驱动模式,门禁打卡系统就可以轻松的在 SaaS 生态中,从零开始,快速打造自己的生态位。


4.如何做一个优秀的事件驱动引擎


前面讲了这么多,了解了什么是事件以及什么是事件驱动架构。也了解到事件驱动架构独特的一些魅力:为什么事件驱动架构,被越来越多的公司喜欢。


最后,我们讲一下,如果要做一个优秀的事件驱动引擎,需要具备哪些能力?我们 RocketMQ EventBridge 怎么做的?


4.1需要什么样的能力?

第一,我们肯定得有一个事件标准。因为事件不是给自己看的,也不是给他看的,而是给所有人看的。事件没有明确的消费者,所有都是潜在的消费者,我们得规范化事件的定义,让所有人都能看得懂,一目了然;


第二,我们得有一个事件中心,事件中心里有所有系统注册上来的各种事件。这个有点类似市场经济大卖场,玲琅满目,里面分类摆放了各种各样的事件,所有人即使不买,也都可以进来瞧一瞧,看一看,有哪些事件,可能是我需要的,那就可以买回去;


第三,我们得有一个事件格式,用来描述事件的具体内容。这相当于市场经济的一个买卖契约。生产者发送的事件格式是什么,得确定下来,不能总是变;消费者以什么格式接收事件也得确定下来,不然整个市场就乱套了;


第四,我们得给消费者一个,把投递事件到目标端的能力,并且投递前,可以对事件进行过滤和转换,让它可以适配目标端 API 接收参数的格式,我们把这个过程统一叫做订阅规则。


第五,我们还得有一个存储事件的地方,就是最中间的事件总线。



4.2如何描述事件

关于刚才提到的第一点事件标准,这个很重要。事件标准,就相当于不同系统之间交流的语言,如果语言都不通,相互交流肯定会出很多问题。我们推荐使用 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\"/>"
}


4.3事件中心

另外,我们必须得有一个事件中心。事件中心对于事件驱动架构来说,是非常重要的一个角色。他就像我们刚才说的市场经济的大卖场,所有的事件,在这个大卖场里,都有详细的使用说明,大家都可以进来瞧一瞧,看一看,觉得合适,就订阅买走。


至于事件中心如何管理,我们可以从API管理里学习很多经验:我们知道 API 包含注册、Schema 描述、Sample、文档、SDK、测试、监控。Event,其实也是一样,它需要在事件中心被注册,定义 Schema 描述、Sample、文档、CodeBinding、测试、监控。


这样消费者拿到这个事件的时候,才知道是什么,怎么用,用的放心。



Schema

事件的 Schema,是用来描述事件中有哪些属性、含义等等信息。为什么我们要引入Schema?一方面是,为了让下游能够理解事件的格式,方便使用事件;另一方面,也是为了限制上游发送事件的格式,发送和修改都必须保障兼容,一旦契约签订,不能轻易修改。我们推荐使用 Json Schema 和 OpenAPI 3.0。


4.4事件过滤和转换

关于事件的过滤和转换,RocketMQ 事件驱动引擎 提供了丰富的事件过滤和转换方式。这些我就不具体一一展开了,详细大家可以上图描述。



4.5RocketMQEventBridge 技术架构

最后,我们 RocketMQ 围绕事件驱动推出的产品,叫做 EventBridge,他的整个架构可以分为两部分:上面是我们的控制面、下面是我们的数据面。


控制面:面向上游,做好事件的管理。通过 EventSource,把上游产生的事件,管理起来,让大家找得到需要的事件,找到事件后,知道怎么用;面向下游,可以通过 EventRule,让消费者,方便的把事件转换成需要的格式,并推送给自己。


中间的 EventBus,是我们存储事件的地方,底下使用的是我们 RocketMQ 自己的Broker;


数据面:是事件的通道,我们除了可以通过 API 发送事件到 EventBus 之外,还可以通过 Source Connector 主动拉事件到 EventBus。消费者创建 EventRule 之后,则可以通过 Sink Connector 将事件,推送到目标端;


除此之外,我们还会有:事件追踪、事件回放、事件分析、事件归档等等。



5.欢迎加入我们


大家如果想进一步了解 EventBridge,可以扫描图片上的二维码,也可以一起参与社区的建设。


RocketMQ EventBridge




相关链接:

[1] 官网

相关实践学习
基于函数计算一键部署掌上游戏机
本场景介绍如何使用阿里云计算服务命令快速搭建一个掌上游戏机。
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
相关文章
|
1月前
|
消息中间件 Cloud Native 物联网
深度剖析 RocketMQ 5.0,事件驱动:云时代的事件驱动有啥不同?
本文技术理念的层面了解一下事件驱动的概念。RocketMQ 5.0 在面向云时代的事件驱动架构新推出的子产品 EventBridge,最后再结合几个具体的案例帮助大家了解云时代的事件驱动方案。
78924 6
|
1月前
|
SQL 分布式计算 数据处理
Uber基于Apache Hudi增量 ETL 构建大规模数据湖
Uber基于Apache Hudi增量 ETL 构建大规模数据湖
52 2
|
1月前
|
SQL 关系型数据库 MySQL
Apache Hudi在信息服务行业构建流批一体的实践
Apache Hudi在信息服务行业构建流批一体的实践
69 2
|
1月前
|
消息中间件 存储 关系型数据库
使用Apache Hudi构建下一代Lakehouse
使用Apache Hudi构建下一代Lakehouse
38 0
|
1月前
|
存储 关系型数据库 Apache
Halodoc使用Apache Hudi构建Lakehouse的关键经验
Halodoc使用Apache Hudi构建Lakehouse的关键经验
40 4
|
1月前
|
存储 分布式计算 数据管理
基于 Apache Hudi + dbt 构建开放的Lakehouse
基于 Apache Hudi + dbt 构建开放的Lakehouse
45 3
|
1月前
|
存储 SQL 分布式计算
基于Apache Hudi + MinIO 构建流式数据湖
基于Apache Hudi + MinIO 构建流式数据湖
84 1
|
10天前
|
消息中间件 存储 Java
深度探索:使用Apache Kafka构建高效Java消息队列处理系统
【4月更文挑战第17天】本文介绍了在Java环境下使用Apache Kafka进行消息队列处理的方法。Kafka是一个分布式流处理平台,采用发布/订阅模型,支持高效的消息生产和消费。文章详细讲解了Kafka的核心概念,包括主题、生产者和消费者,以及消息的存储和消费流程。此外,还展示了Java代码示例,说明如何创建生产者和消费者。最后,讨论了在高并发场景下的优化策略,如分区、消息压缩和批处理。通过理解和应用这些策略,可以构建高性能的消息系统。
|
1月前
|
消息中间件 Cloud Native 物联网
深度剖析 RocketMQ 5.0,Apache RocketMQ:如何从互联网时代演进到云时代?
从整体技术架构上学习 RocketMQ 5.0 的云原生架构、一体化架构,最后再分别从业务场景切入,详细介绍 RocketMQ 5.0 在不同的业务场景提供的能力和关键技术原理,包括业务消息、流处理、物联网以及面向云时代的事件驱动场景。
107558 1
|
1月前
|
SQL 分布式计算 NoSQL
使用Apache Hudi和Debezium构建健壮的CDC管道
使用Apache Hudi和Debezium构建健壮的CDC管道
17 0

热门文章

最新文章

相关产品

  • 云消息队列 MQ
  • 推荐镜像

    更多