理解事件驱动架构(EDA)中的概念
事件驱动架构近年来已成为开发高度可扩展分布式系统的热门选择。它是一种软件设计方法,系统的不同部分通过发送和响应事件进行通信。
事件是发生的事情,例如:
- 用户注册
- 用户上传照片
- 付款已完成
系统的不同部分不是直接向彼此发出请求,而是监听这些事件并在需要时(异步)做出反应。
例如:
- 支付服务已完成并发出事件:“支付完成”。
- 库存服务监听该事件并更新已购买的新产品的库存。
- 电子邮件服务监听并发送确认电子邮件。
让我们看一下事件驱动架构中组件的简单图表
关键组件
1. 事件生产者/发布者:
当事件发生时创建并发出事件的系统或服务。
例如:当新用户注册时,用户服务会发送“用户已注册”事件。
2. 消息代理
消息代理是充当事件生产者和事件消费者之间的中介的中间件。其主要作用是高效地接收、存储和路由事件,确保事件被传递到正确的消费者服务。
在此背景下,消息代理内部有一个关键概念,称为“通道”。这些通道充当通信路由,协调从生产者到正确消费者的事件流。
- 在Kafka中,这些通道被称为主题 (Topic)。它支持多订阅者模型,允许多个消费者监听同一个发布者的消息。
- 在RabbitMQ中,这些通道被称为队列。RabbitMQ 的队列通常是点对点的,这意味着只有一个消费者可以处理来自队列的消息。
示例技术:Kafka、RabbitMQ、AWS SNS/SQS、Google Pub/Sub。
3. 事件消费者/订阅者
监听事件并做出响应的服务。
例如:通知服务监听“用户已注册”并发送欢迎邮件。
4. 事件:
描述事件发生情况的实际消息。它通常包含结构化数据(JSON、XML)。
事件消息示例:
{
"data": {
"id": "event-123456",
"type": "user.event.registered",
"timestamp": "2025-04-01T12:00",
"attributes": {
"id": "usr-98765",
"email": "user@example.com",
"surname": "example",
}
}
}
经纪交易所
在消息代理中,交换机是一种路由机制,用于确定消息如何传递到队列。不同类型的交换机提供不同的消息分发模式。
直接交换(1:1 路由)
根据路由键和队列绑定键(RabbitMQ)的精确匹配,将消息路由到队列。
它是如何工作的?
- 生产者发送带有路由键的消息。
- 交换机仅将消息转发到具有匹配绑定键的队列。
示例:
带有路由键 = 的消息"order.created"
仅进入与 绑定的队列"order.created"
。
扇出交换(广播)
将消息发送到所有绑定队列,忽略路由键
(RabbitMQ-扇出交换 | Kafka-每个主题多个消费者)。
它是如何工作的?
- 生产者发送一条消息。
- 交换机将消息复制到与其绑定的所有队列。
示例:
通知事件被广播到多个服务(电子邮件、短信、推送通知)。
主题交换(模式匹配)
根据路由键中的通配符模式路由消息。支持*
,匹配一个单词,以及#
,匹配多个单词。(RabbitMQ 主题交换 | Kafka 带分区键的主题)。
它是如何工作的?
- 用于
.
分隔路由键中的单词("order.payment.failed"
)。
示例:
绑定到的队列"order.*"
接收"order.created"
和"order.cancelled"
,但不接收"user.created"
。
EDA 的优势-反应式宣言
- 可扩展性:解耦的服务可以独立扩展。
- 灵活性:无需修改现有服务即可轻松添加新的事件消费者。
- 实时处理:实现实时数据流和快速响应。
- 弹性:只要事件和订阅得到妥善管理,单个服务的故障就不会影响整个系统
- 松散耦合:组件通过事件进行交互,减少依赖性。
EDA的缺点:
- 最终一致性:系统的不同部分可能会暂时拥有过时的信息,直到所有事件都被处理。
- 复杂的调试:跨多个异步事件追踪问题更加困难。
- 增加延迟:由于异步特性,某些事件可能需要更长时间才能处理。
- 事件重复:需要幂等性以避免重复处理。
- 事件排序问题:一些代理不保证消息顺序(RabbitMQ)。
- 学习曲线:需要事件驱动设计模式方面的专业知识。
结论
如果您正在考虑实现一个分布式、实时且高度可扩展的系统,那么您绝对应该考虑实现一个事件驱动的架构,以充分利用它提供的所有优势。
文章来源:https://dev.to/jhonifaber/introduction-to-event-driven-architecture-eda-3ioj