RocketMQ EventBridge 概述
RocketMQ EventBridge 专注于帮助用户构建高可靠性、低耦合、高性能的事件驱动架构。在事件驱动架构中,微服务不需要主动订阅外部消息,而是可以将所有触发微服务系统变化的条目集中到 API,只需要专注于当前微服务的业务领域模型定义和 API 设计,而无需通过大量粘合代码来适应和解析外部服务消息。EventBridge 负责安全可靠地将外部服务生成的事件适配并传递到当前微服务设计的 API。
我们什么时候使用 RocketMQ 消息,什么时候使用 EventBridge 事件?事件的含义是什么,与消息有什么区别?
消息与事件
我们定义事件如下
Events refer to things that have already happened, especially important things.
事件与消息的关系如下:
消息包括命令消息和事件消息。命令消息是外部系统发送到本系统的操作指令(如图左侧所示);事件消息是系统收到命令操作请求后发生的内部变化事件(如图右侧所示);
事件的四个特征
1. 已经发生
事件总是“已经发生”。“已经发生”也意味着它们是不可变的。这个特性非常重要,当我们处理事件和分析事件时,意味着我们可以绝对信任这些事件,只要我们收到事件,它们就一定是系统的真实行为。
命令代表一个操作请求,它是否真正发生是无法知道的。例如:
* Turning on the kitchen lights
* Someone pressed the doorbell
* Account A received 100,000.
事件是已经发生的明确事件,例如
* The kitchen light being turned on
* Someone pressing the doorbell
* Account A receiving 100,000
2. 没有预期
An event is an objective description of a change in the state or attribute value of a thing, but it does not make any expectations about how to handle the event itself. In contrast, both Command and Query have expectations, they hope the system will make changes or return results, but the Event is just an objective description of a change in the system.
例如:交通信号灯,从绿灯变黄灯,仅仅描述一个客观事实,本身没有客观预期。在不同的国家和地区,对这个事件赋予了不同的预期。例如,在日本,黄灯等同于红灯,而在俄罗斯,闯黄灯是可以容忍的。
与命令消息相比:
- 事件:有点像“市场经济”,商品生产出来,放在商场的大橱窗里,消费者觉得好就买回去,没人买,商品可能过期浪费。
- 命令消息:有点像“计划经济”,生产是根据需求,指定分配对象,浪费很少。
3. 自然有序且唯一
The same entity cannot have both A and B occur at the same time, there must be a temporal relationship; if so, these two events must belong to different event types.
例如:对于同一个交通信号灯,它不可能同时变绿灯和红灯,它只能在给定的时刻变为一种状态。如果我们看到两个内容相同的事件,那么它一定发生了两次,并且其中一次发生在另一次之前。这对处理数据一致性和系统行为分析(如 ABA 场景)很有价值:我们不仅看到了系统的最终结果,还看到了导致该结果的中间过程。
4. 物化
事件试图尽可能完整地记录“犯罪现场”,因为事件不知道消费者将如何使用它们,所以它们会尽可能详细。包括
When did the event occur?
Who generated it?
What type of event is it?
What is the content of the event? What is the structure of the content?
... ...
与我们看到的普通消息相比,由于上游和下游通常是确定的,为了提高性能和传输效率,消息会尽可能简洁,只要满足“计划经济”指定的消费者需求即可。
RocketMQ EventBridge 的典型应用场景
场景 1:事件通知
在微服务中,我们经常遇到一个微服务中产生的消息需要通知其他消费者的场景。这里我们比较三种方式
A:强依赖方式
生产者主动调用消费者的微服务,并适配消费者的 API。这种设计无疑非常糟糕,生产者强依赖于消费者,深度耦合。如果调用消费者出现异常,没有进行有效的隔离,很可能导致整个微服务挂掉。当新的消费者进来时,它非常糟糕。
B:半解耦方式
生产者将消息发送到消息服务,消费者订阅消息服务获取消息,并将消息转换为自身业务领域模型所需的数据格式。这种方式在调用链上实现了解耦,大大降低了系统风险,但对于消费者来说,他们仍然需要理解和解析生产者的业务语义,并将消息转换为自身业务领域所需的格式。在这种方式下,当消费者需要订阅多个生产者的数据时,需要大量的粘合代码来适应每个生产者产生的消息。此外,当上游生产者的消息格式发生变化时,也存在风险和运维成本。
C:完全解耦方式
在这种方式下,消费者不需要引入 SDK 来订阅 Broker,他们只需要根据自己的业务领域模型设计 API,消息服务会过滤和转换上游
场景 2:跨系统集成
场景 1 主要关注单一产品内微服务之间的事件通信。场景 2 主要关注多个产品之间的事件通信。在一个企业中,我们经常使用多个产品,其中很多产品可能不是我们自己开发的,而是作为外部 SaaS 服务购买的。在这种情况下,很难让不同外部 SaaS 产品之间的事件流动起来,因为这些外部 SaaS 产品不是我们自己开发的,修改它们的代码并不容易。EventBridge 提供的事件中心能力可以帮助收集各种产品生成的事件,并对其进行良好的组织和管理,就像商场橱窗里的商品一样,精心排列,并配有说明,供消费者选择,也提供送货上门服务。
RocketMQ EventBridge 如何工作?
为了解决上述两个场景中提到的问题,EventBridge 从五个方面入手
1. 确定事件标准
因为事件不是为自己,而是为所有人。它没有明确的消费者,所有都是潜在的消费者。因此,我们需要规范事件的定义,让所有人都能理解,并且易于理解。目前,CNCF 下的 CloudEvent 已经逐渐成为一个被广泛认可的事实标准,因此我们选择 CloudEvent 作为我们的 EventBridge 事件标准。
2. 建立事件中心
事件中心包含各种系统注册的所有事件。这就像我们上面提到的市场经济百货商店,它有各种各样的事件分类和排列,每个人都可以进来看看哪些事件可能需要,然后买回去。
3. 定义事件格式
事件格式用于描述事件的具体内容。这相当于市场经济中的销售合同。生产者发送的事件格式必须确定,不能总是改变;消费者接收事件的格式也必须确定,否则整个市场就会混乱。
4. 订阅“规则”
我们需要给消费者提供将事件传递到目标端的能力,并在传递前过滤和转换事件,使其能够适应目标端 API 接收参数的格式。我们称这个过程为创建订阅规则。
5. 事件总线:最后,我们还需要一个地方来存储事件,那就是图中中间的事件总线。