问题描述
我们已将微服务设置为使用 rabbitmq
队列来处理任何即将到来的数据。
因此,我们有 service A
、service B
、service C
和 service D
。
当请求创建一个用户到 service A
时,它会创建一个用户并将一个事件推送到 newUserIsCreated
队列。
现在,service B
和 service C
需要为新添加的用户更新他们的数据库。
问题:
如果用户创建在任何 service B
和 service C
中失败怎么办。
可能的失败场景可能是验证失败,或者 service B
和 service C
已关闭。
如果 service D
尝试访问同一用户,也会出现问题。
service B
和 service C
会用什么回应?因为到那时他们将没有新创建的用户。
总结一下,
如何处理验证失败或这些服务之间的任何类型的失败?
如果需要实时同步怎么办? (处理队列可能需要一些时间)
解决方法
您可以让 B
和 C
(以及任何其他需要确认用户已创建的服务)向 RabbitMQ 发布一条确认消息以供 A
接收; A
然后在收到确认之前不会确认用户已创建。这并非万无一失:它很有可能在任何地方都成功,但 A
没有及时得到确认。对于这种(理想情况下很少见)的情况,您可以制定一个清理流程。
不过值得注意的是,这种同步关系基本上是通过消息队列重新实现请求/响应,所以如果沿着这条路径走,为什么不直接执行请求/响应(例如 HTTP 或 gRPC)?
如果你有一个需要影响多个服务的操作,将它建模为一个 saga 通常很有用,它将向各种服务发出请求并处理失败(如果失败太多,可能会放弃,滚动返回它所做的更改)。通过持久化 saga 的状态(例如已更新 B
,但 C
尚未确认更新),可以对其进行查询。
如果您发现 B
中的大多数操作都是涉及 A
的 sagas 的一部分,那么可能值得考虑 B
和 A
是否应该是同一个服务,这将实现更强的一致性保证,也可能简化事情。