事件驱动微服务的架构
我们可以使用事件驱动微服务 (EDM) 发送和接收事件消息。生产者生成并发布事件,以在系统中发生操作和更改时通知其他服务。同时,其他服务使用这些事件采取相关操作以实时更新。
EDM 系统的主要优势在于其异步通信和松散耦合的设计。服务在事件发生时订阅并做出反应,而不是等待在需要时请求数据。EDM 是松散耦合的,以保持微服务之间的独立性。因此,我们可以单独操作和扩展任何服务而不会相互影响。
EDM 具有松散耦合的架构和事件驱动的基础。EDM 可以解决传统方法的局限性。我们将在本章中讨论这些解决方案。
REST 驱动方法
我们在基于 REST 的同步系统中相互调用组件并等待响应 −
但是这种方法存在一些问题,包括以下内容 −
- 对响应的依赖 − 如果模块 1 等待模块 2 的响应。那么如果模块 2 很慢且不可用,它可能会有延迟。
- 服务停机时间 − 如果服务停机。那么其依赖的服务就会中断。
- 网络延迟 −对于需要分页的大型有效负载,数据传输可能会延迟。
- 重负载影响 − 重负载下的服务可能响应缓慢。因此会降低性能。
当系统由于这些同步连接而变得效率低下时,我们会使用 EDM 解决方案。
事件驱动的微服务示例
假设我们有一个报告应用程序 GIB API,用于向政府发送销售报告。此应用程序从另一个 API 获取所有销售数据。一开始,由于交易量很少,我们使用简单的 REST 方法构建了 API。
但是当数据增长时,交易量会意外增加。 REST 方法存在问题,因此我们需要一个事件驱动的解决方案。
解决方案 1:转换为事件消息传递
我们应用事件驱动方法来高效生成报告。该计划很简单,如下所示 −
- 为新交易生成事件 − 每当创建新交易项时,都会发布事件。
- 异步数据获取 − 获取相关数据并将其转换为报告内容。
- 存储和检索报告 − 报告数据存储在关系数据库 (PostgreSQL) 中。报告字符串被连接起来并保存为文件以供以后访问。
通过这种异步事件消息传递。报告应用程序可以处理数据,而无需不断进行直接 REST 调用。
将流程转换为异步模型后,还存在另一个性能问题。报告 API 仍在使交易 API 过载,因为它请求每个项目的交易详细信息。
解决方案 2:Fat Event
我们可以使用"Fat Event"方法来解决上述问题。每条事件消息都包含所有相关的交易详细信息。我们将数据直接嵌入到每个事件中。因此,它消除了对额外 REST 调用的需求。它创建了一个完全异步的 EDM 架构。
{ "identifier": 2, "detail": "sale transaction item", "created_date": 4587997988425, "last_modified_date": 1845298016540 }
完整的事件驱动架构
整个系统对大量事件的响应更快。我们在事件中拥有所有必要的信息。每个服务都可以独立运行,而无需实时依赖其他服务。
解决方案 3:发件箱模式
我们将处理的数据视为金融交易。保持准确性很重要。这需要一种可靠的方法来确保所有事件都得到传递和处理,而不会丢失任何数据。在这里,我们应用了发件箱模式。
什么是发件箱模式?
我们首先在发件箱模式中的数据库表中保存事件消息,而不是直接发布事件消息。然后,作业会将这些事件分批处理并定期发送。
Outbox Pattern 工作流
- 事件生成 − 业务模块发布事件。
- 持久化事件 − 事件服务将事件消息存储在关系数据库 (RDBMS) 中。
- 触发作业 − 调度程序启动发送事件消息作业。
- 发布消息 −事件服务检索存储的事件并使用 RabbitMQ 等消息代理发布这些事件。
发件箱模式的优势
- 持久事件 − 由于事件保存在关系数据库中,因此它具有 ACID 属性,因此数据是持久的。
- 丢失事件的恢复 − 如果事件发布失败。它可以从数据库中重新发送。
发件箱模式的缺点
- 增加了复杂性 − 因为它在架构中添加了另一层管理。
- 延迟发布 −事件可能会按间隔发布,而不是实时发布。
EDM 架构的优势
下面给出了使用 EDM 架构的一些优势 −
- 松散耦合结构 − 每个微服务都是独立的,因此具有灵活性和模块化。
- 完全隔离 − 每个微服务无需同步调用其他服务即可运行。
- 异步处理 − 它提高了整个系统的响应能力和效率。
- 性能提升 − 服务可以在事件发生时做出反应。
EDM 的主要优点是松散耦合。它保留了微服务的独立性。
EDM 具有单点故障
如果您在 EDM 中使用 RabbitMQ 等消息代理,则它可能存在故障点。
但您可以使用以下技术之一解决此问题 −
- 集群配置 − 您可以将 RabbitMQ 设置为集群以防止单点故障。
- 持久队列 − 您可以配置队列以持久保存。
- 消息持久性 −您可以存储消息以供以后检索,即使在代理暂时中断的情况下也是如此。
如果发生错误,集群中的其他实例可以接管。因此可以恢复持久化的消息。
重复事件消息
有时,一个事件可能会发布多次。但您可以使用以下技术来防止重复消息问题 −
幂等消费者 − 消费者应该用于处理重复事件。在采取行动之前,它应该首先检查这些消费者是否已经处理过事件。
在微服务架构中,您需要保持松散耦合以实现有效通信。您可以使用事件驱动 (EDM) 方法来减少对直接 REST 调用的依赖。EDM 避免了同步通信的问题,例如等待响应和处理服务中断。
我们设置了一个带有持久化消息的 RabbitMQ 集群。服务可以发布事件而无需立即确认。胖事件包含提高效率所需的所有数据。发件箱模式具有可靠的事件传递,即使在出现网络问题和临时中断的情况下也是如此。
结论
EDM 用于保持微服务的独立性和松散耦合。您可以高效且可扩展地处理 EDM 中的实时数据。但是,如果微服务变得相互依赖。那么架构就有转变为分布式整体的风险。因此,您应该使用事件驱动的设计来保持松散耦合。