在刚刚过去的 RocketMQ Summit 2022 全球开发者峰会上,我们对外正式开源了我们的新产品 RocketMQ-Eventbridge 事件驱动引擎。
RocketMQ 给人最大的印象一直是一个消息引擎。那什么是事件驱动引擎?为什么我们这次要推出事件驱动引擎这个产品?他有哪些应用场景,以及对应的技术方案是什么?
今天我们就一起来看下,整篇文章包含三部分:
第一部分,我们一起看下什么是事件。
第二部分,和大家一起看看,事件有哪些不一样的“超能力”,使用这些“超能力”呢,我们又能干些什么?
第三部分,我们讲一下 RocketMQ 给出的关于事件的解决方案,也是我们这次开源的项目:RocketMQ-EventBridge。
大家自己可以先在脑袋里想一下,什么是事件?我们给事件下的一个定义是:
过去已经发生的事,尤其是比较重要的事。
A thing that happens, especially one of importance.
这个很好理解。比如说,昨天下午我做了一次核酸检测;今天上午又吃了一个冰激淋。这些都是过去已经发生的事件。但是,如果我再问:事件跟消息有什么区别?这个时候,大家是不是觉得事件这个定义,好像又不那么清晰?
刚才说的那些事件,是不是也可以理解为消息啊?如果,老张给我发送了一条短信,这个算是事件,还是消息啊?平常开发过程中,“什么时候使用消息,什么时候使用事件?”
不过,在回答这个问题之前,我们一起来看一个典型的微服务。
一个微服务系统和外部系统的交互,可以简单分为两部分:一是接收外部请求(就是图中上面黄色的部分);二是是调用外部服务(就是图中下面绿色的部分)。
接收外部请求,我们有两种方式:一种是提供 API,接收外部发过来的 Query 请求和 Command 请求;另外一种是主动订阅外部 Command 消息。这两类操作,进入系统内部之后呢,我们常常还会,调用其他为微服务系统,一起协同处理,来完成一个具体的操作。当这些操作,使得系统状态发生改变时,就会产生事件。
这里呢,我们把从外部接收到的 Command 消息,和系统内部产生的事件,都称之为消息。
我们总结一下,消息和事件的关系是这样的:消息包含两部分,Command 消息和 Event 消息
1、看图中左半部分,Command 是外部系统发送给本系统的一条操作命令;
2、再看图中右半部分,Event 则是本系统收到 Command 操作请求,系统内部发生改变之后,随之而产生了事件;
所以,事件和消息是不同的,事件可以理解为是一种特殊的消息。其特殊的点,主要在 4 个地方:
事件,一定是“已发的”。“已发生”的代表什么呢?不可变的。我们不可能改变过去。这个特性非常重要,在我们处理事件、分析事件的时候,这就意味着,我们绝对可以相信这些事件,只要是收到的事件,一定是系统真实发生过的行为。而且是不可修改。
对比 Command 和 Query。Command 的中文是什么?命令。很显然,它是还没有发生的,只是表达了一种期望。我们知道“期望的”,不一定会成功发生
比如:把厨房的灯打开、去按下门铃、转给 A 账户 10w……
这些都是 Command,都是期望发生的行为。但是,最终有没有发生?并不知道
Event 则是明确已经发生的事情。比如:厨房灯被打开了、有人按了门铃、A 账户收到了 10w……
再对比 Query,它则是查询系统当前状态的一种请求,比如:厨房的灯是打开着的、门铃正在响、查下账户显示余额 11w……
这个怎么理解?事件是客观的描述一个事物的状态或属性值的变化,但对于如何处理事件本身并没有做任何期望。
相比之下,Command 和 Query 则都是有期望的,他们希望系统做出改变或则返回结果,但是 Event 呢,它只是客观描述系统的一个变化。
我们看一个例子:交通信号灯,从绿灯变成红灯,事件本身并没有要求行人或汽车禁止通行,而是交通法规需要红绿灯,并赋予了其规则。
所以,系统一般不会定向的、单独向另外一个系统发送事件,而是统一的告诉“事件中心”,“事件中心”呢,那里面有各个系统上报上来的,各式各样的事件。系统会向事件中心说明:自己这个系统,会产生哪些事件呀,这些事件的格式是怎么样的呀。
别的系统如果感兴趣呢,就可以来主动订阅这些事件。真正赋予事件价值的,是事件消费者。事件消费者想看看,某个系统发生了什么变化呀?OK,那他就去订阅这些事件,所以事件是消费者驱动的。
这跟消息有什么区别呢?Command 消息的发送和订阅,是双方约定好的,外人不知道,往往是以文档或代码的形式,大家按约定好的协议,发送和订阅消费,所以消息是生产者驱动的。
我们打个比喻,事件就像市场经济,商品被生产出来,具体有什么价值,有多大价值,很大程度上看其消费者。我们能看到