消息和事件系统
了解消息传递和事件驱动架构如何实现解耦、可扩展的后端通信。
为什么会存在消息系统
消息系统通过允许服务通过 broker 异步通信,而不是直接调用,从而降低耦合。
- 服务之间的直接调用会在系统之间产生紧密依赖。
- 消息传递引入了一个 broker,用于解耦生产者和消费者。
- 服务可以异步通信,而不必彼此等待。
详情
在传统系统中,一个服务会直接调用另一个服务来完成任务。这会造成紧密耦合——如果某个服务变慢、不可用或负载过高,就会直接影响调用方。
消息系统通过在服务之间引入 message broker 来解决这个问题。服务不再直接调用另一个服务,而是把消息发送到 broker,由接收服务独立处理。
这实现了异步通信。发送方不需要等待接收方完成处理,从而提升了系统的响应速度和弹性。
通过解耦服务,消息系统让单个组件更容易扩展、维护和演进,而不会破坏整个系统。
消息队列
消息队列通过将任务存储起来,直到消费者准备好处理它们,从而实现异步通信。
- 生产者将消息发送到队列,而不是直接调用另一个服务。
- 队列会保存消息,直到消费者处理它们。
- 这使得异步处理成为可能,并解耦系统组件。
详情
消息队列充当生产者和消费者之间的缓冲区。消息不会要求立即处理,而是会存储在队列中,直到有消费者可用来处理它们。
这使系统能够异步处理任务。例如,Web 请求可以快速将一个任务入队(比如发送电子邮件),而无需等待任务完成。
队列还提高了可靠性。如果消费者失败或暂时不可用,消息会保留在队列中,并可以稍后处理。
通过分离生产者和消费者,消息队列减少了系统依赖,并允许每个组件独立扩展。
发布 / 订阅(Pub/Sub)
Pub/Sub 使一个事件能够分发给多个消费者,而它们之间没有直接连接。
- 发布者将消息发送到一个 topic,而不是针对特定消费者。
- 多个订阅者会同时接收同一个事件。
- 这种模式支持事件广播和松耦合。
详情
在 publish/subscribe 模型中,发布者将消息发送到一个 topic,而不是直接发送给某个特定消费者。
消费者订阅该 topic,并自动接收发布到其中的任何消息。这使得一个事件可以在系统中触发多个独立操作。
例如,当用户注册时,一个事件就可以通知多个服务——例如 email、analytics、billing 和 notifications——而发布者无需知道它们的存在。
这种模型将生产者与消费者解耦,使系统更容易扩展。可以在不修改发布者的情况下添加或移除新的订阅者,从而提升灵活性和可扩展性。
Pub/Sub 广泛用于 event-driven architectures,在这些架构中,系统通过响应事件来工作,而不是依赖直接的同步通信。
事件驱动系统
事件驱动系统使服务能够通过发出和响应事件来进行通信,从而减少组件之间的直接依赖。
- 服务发出事件(例如,“User Created”),而不是直接调用其他服务。
- 多个独立服务可以在无需协调的情况下对同一个事件做出反应。
- 这使系统解耦,让每个服务都能独立扩展和演进。
详情
在事件驱动系统中,动作是由事件触发的,而不是由服务之间的直接调用触发的。当某件事发生时——例如新用户注册——系统会发出一个描述该变化的事件。
这个事件会通过消息代理进行传递,多个服务可以订阅并对其作出反应。例如,一个 “User Created” 事件可以触发邮件服务发送欢迎消息,分析服务跟踪用户增长,以及计费服务初始化账户。
与传统的请求-响应系统不同,事件的生产者不需要知道哪些服务会消费它。这消除了紧耦合,并允许在不影响其他服务的情况下添加、移除或修改服务。
这种架构提高了可扩展性,因为每个服务都可以按照自己的节奏处理事件。它也提高了弹性——如果某个服务失败,其他服务仍然可以继续运行,不会被阻塞。
不过,事件驱动系统也会引入复杂性,例如处理事件顺序、重复事件,以及服务之间的最终一致性。
事件溯源
事件溯源将每一次变更都存储为一个事件,从而允许系统状态在任意时间点被重建。
- 系统不再只存储当前状态,而是存储一系列事件。
- 当前状态通过按顺序回放这些事件来推导。
- 这使得审计、历史跟踪以及可复现的系统状态成为可能。
详情
在传统系统中,数据库通常只存储数据的最新状态。事件溯源采用不同的方法,它将每一次变更都作为事件存储在一个仅追加的日志中。
例如,系统不会只存储当前的用户资料,而是记录像 "UserCreated"、"EmailUpdated" 和 "PasswordChanged" 这样的事件。这些事件代表了完整的变更历史。
当前状态是通过按顺序回放这些事件来重建的。这使系统能够在任意时间点重建状态,这对于调试、审计和分析都很有用。
这种方法提供了很强的可追溯性,并且可以准确了解系统是如何达到当前状态的,但它也会在存储和处理方面引入额外的复杂性。
消息代理
消息代理充当中介,负责管理消息在服务之间的存储、路由和传递方式。
- 消息代理接收来自生产者的消息,并将其传递给消费者。
- 它们提供可靠投递和消息持久化等保证。
- 它们处理路由逻辑,以确保消息到达正确的消费者。
详情
消息代理位于生产者和消费者之间,作为管理消息流的中心系统。
当生产者发送消息时,代理会存储该消息,并确保它被传递给合适的消费者。这样就不需要各个服务彼此直接通信。
消息代理还提供投递保证。根据系统不同,消息可以持久化到磁盘以防止数据丢失,并且在投递失败时进行重试。
它们还负责路由,决定哪些消费者应该接收哪些消息。这可以是简单的基于队列的投递,也可以是更复杂的模式,例如 pub/sub 主题。
通过集中处理这些职责,消息代理简化了通信,并使分布式系统更加可靠和可扩展。
常见消息传递技术
不同的消息系统是为不同的性能、可靠性和架构需求而设计的。
- Kafka 专为高吞吐量事件流和持久化日志而构建。
- RabbitMQ 侧重于可靠的消息传递和灵活的路由。
- NATS 针对微服务中的低延迟通信进行了优化。
详情
Kafka 是一个分布式事件流平台,旨在处理海量数据。它将消息存储在持久化日志中,并允许消费者重放事件,因此适用于分析流水线和事件驱动系统。
RabbitMQ 是一种传统的消息代理,支持队列和复杂的路由模式。它专注于可靠传递,通常用于后台作业处理和任务队列。
NATS 是一种轻量级消息系统,设计目标是简单和快速。它提供非常低的延迟通信,常用于微服务架构中,因为在这些场景下快速消息传递至关重要。
每种系统都有不同的权衡。Kafka 优先考虑吞吐量和持久性,RabbitMQ 强调灵活性和可靠性,而 NATS 则专注于速度和简单性。选择合适的工具取决于系统需求。
分布式系统中的消息传递
消息传递系统在保持分布式服务彼此独立且可扩展的同时,协调它们之间的通信。
- 服务通过 broker 进行通信,而不是直接连接。
- 消息传递通过缓冲和重试消息来提高容错能力。
- 它支持跨多个独立服务的可扩展通信。
详情
在分布式系统中,多个服务独立运行,并且通常位于不同的机器上。协调它们之间的通信成为一个主要挑战。
消息传递系统通过引入 message broker 作为中心通信层来解决这个问题。服务通过 broker 发送和接收事件,而不是直接相互调用。
这种解耦提高了容错能力。如果某个服务暂时不可用,消息可以保留在系统中,稍后再处理,而不会阻塞其他服务。
它还提高了可扩展性。可以添加新的服务来消费事件,而无需修改现有服务,从而让系统在没有紧密依赖的情况下扩展。
因此,消息传递系统是现代分布式架构中的基础组件,能够支持灵活、弹性且可扩展的系统设计。
问题部分
1 / 5
此课程属于高级内容
升级到高级版以去除模糊效果并解锁完整内容。