使用rabbitmq队列处理微服务之间的实时数据同步

问题描述

我们已将微服务设置为使用 rabbitmq 队列来处理任何即将到来的数据。

因此,我们有 service Aservice Bservice Cservice D

当请求创建一个用户service A 时,它会创建一个用户并将一个事件推送到 newUserIsCreated 队列。

现在,service Bservice C 需要为新添加用户更新他们的数据库


问题

如果用户创建在任何 service Bservice C 中失败怎么办。

可能的失败场景可能是验证失败,或者 service Bservice C关闭

如果 service D 尝试访问同一用户,也会出现问题。

service Bservice C 会用什么回应?因为到那时他们将没有新创建的用户


总结一下,

如何处理验证失败或这些服务之间的任何类型的失败?

如果需要实时同步怎么办? (处理队列可能需要一些时间)

解决方法

您可以让 BC(以及任何其他需要确认用户已创建的服务)向 RabbitMQ 发布一条确认消息以供 A 接收; A 然后在收到确认之前不会确认用户已创建。这并非万无一失:它很有可能在任何地方都成功,但 A 没有及时得到确认。对于这种(理想情况下很少见)的情况,您可以制定一个清理流程。

不过值得注意的是,这种同步关系基本上是通过消息队列重新实现请求/响应,所以如果沿着这条路径走,为什么不直接执行请求/响应(例如 HTTP 或 gRPC)?

如果你有一个需要影响多个服务的操作,将它建模为一个 saga 通常很有用,它将向各种服务发出请求并处理失败(如果失败太多,可能会放弃,滚动返回它所做的更改)。通过持久化 saga 的状态(例如已更新 B,但 C 尚未确认更新),可以对其进行查询。

如果您发现 B 中的大多数操作都是涉及 A 的 sagas 的一部分,那么可能值得考虑 BA 是否应该是同一个服务,这将实现更强的一致性保证,也可能简化事情。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...