微服务的业务事务异步通信

问题描述 投票:0回答:1

问题

在微服务架构中,考虑一个

service A
,它接收来自用户的请求并将一些数据保存到其数据库中。

一旦坚持,

service A
必须通知
service B
service B
的通知操作可以异步发生(不需要立即)。

设计

实现上述要求的几种方法可能是:

方法#1

  1. service A
    将数据持久保存(插入+提交)到数据库中
  2. 将消息推入队列以供
    service B
    消费
  3. 向用户返回成功

方法#2

  1. service A
    将数据持久保存(插入+提交)到数据库中
  2. CDC 和 KAFKA 的交易发件箱模式
  3. service B
    是 KAFKA 中主题的订阅者并获取消息

问题

  1. 与选项2相比,选项1非常简单。但是,它引入了双重写入问题。在我之前的组织(一家中型初创企业)中,我们广泛遵循选项 1(使用 aws sqs),没有任何问题。是因为 aws 提供了 99.9% 的可用性 SLA,并且很幸运从未遇到过任何重大问题吗?双写问题真的有那么值得担心吗?
  2. 还有其他办法吗?
rest events design-patterns architecture microservices
1个回答
0
投票

适合您情况的消息系统相关故障模型

  1. 数据库事务已提交,但消息队列暂时不可用
  2. 数据库事务已提交,但消息代理拒绝消息
  3. 数据库事务已提交,但消息代理未及时响应

方法#1

如果您的应用程序和消息系统之间存在暂时性网络问题,那么根据需求,重试机制可能会有所帮助。但是在失败的重试尝试期间,您必须将未传递的消息存储在某处。如果您使用节点本地非持久队列,那么您的应用程序在应用程序崩溃或节点重新启动时很容易丢失消息。如果您有一个节点本地持久队列来存放要重试的消息,那么您的应用程序及其监控将变得更加复杂。

如果消息代理返回否定确认(nack),那么根据许多因素,您可能想要重试该消息/将其放入死信队列(DLQ)/丢弃它/...

如果您的应用程序在给定时间范围内没有收到经纪人的任何确认,那么您可以怀疑您遇到了暂时性网络问题。

方法#2

如果您的 CDC 进程暂时无法到达消息系统,那么它将稍后重试。它不必担心要重试的消息的持久性,因为它们作为发件箱模式的一部分提交到数据库中。一些复杂的 CDC 进程可以使用

maxRetry
配置进行配置,以不无限期地重试。

其他两个故障模型的处理方式与方法 #1 的情况相同。


请记住,在方法#2 的情况下,CDC 流程可能不会连续地、只是定期地进行消息迁移。这意味着由于基于时间或消息数量的缓冲而存在额外的延迟。

© www.soinside.com 2019 - 2024. All rights reserved.