【问题标题】:ACID like communication between microservices pattern类似 ACID 的微服务模式之间的通信
【发布时间】:2020-10-05 04:26:37
【问题描述】:

过去几个月我一直在研究微服务架构应用程序,但我仍在努力适应分布式特性。我多次注意到一种模式,但我不确定处理它的首选方式是什么。

假设我们有服务 A、服务 B 和服务 C。服务 A 公开一个 API,其中一种方法依赖于调用 B 公开的 API 来创建资源 RB,还依赖于 C 公开的 API 来创建资源资源 RC。因此,在一个完美的世界中,A、B 和 C 都可以正常工作,但我注意到几次的用例是,在执行 A 公开的 API 逻辑期间,B 或 C 可能会关闭。甚至更多是如何做到的应该在创建 RB 时解决,C 已关闭,因此无法创建 RC,我们尝试通过在服务 B 上调用 /delete/ 来回滚 RB 的创建,但在此期间 B 也关闭了。现在RB被创建了,但最终它不应该,因为RC失败了,A的API逻辑应该执行。

相同的 A、B 和 C 可能是集群环境中的 3 个节点,当数据发布到其中一个节点时,尝试在集群中传播数据。

抱歉,文字太长了, 谢谢。

【问题讨论】:

  • 查找最终一致性

标签: api design-patterns architecture microservices rollback


【解决方案1】:

这个问题已有数十年的历史,并且有许多不同的方法可以解决它。问题在于,实际实现您所描述的内容所需的分布式事务管理类型很难正确处理,并且往往会导致解决方案过于复杂。这种复杂性确实是 EJB 之类的东西走上渡渡鸟之路的真正原因。

随着时间的推移,事情已经发展到这样的程度:在大多数情况下,让事情最终保持一致并将重试转移到不同类型的消息队列等变得更容易(如之前的海报所述)。当然,有些情况你根本无法最终保持一致,但它们并不难识别,而且是少数。

【讨论】:

    【解决方案2】:

    将这些错误消息保存到队列中,并让后台作业重试回滚。

    【讨论】:

      【解决方案3】:

      您遇到的问题是服务之间的其余调用,这样做是在服务之间进行时间耦合,因此,如果在那一刻任何服务关闭,所有操作都会失败,最糟糕的是如您所说,您的数据可能存在不一致。

      在分布式系统中处理故障的最佳方法是创建一个反应式系统。这是反应式宣言的链接。

      https://www.reactivemanifesto.org/

      他们说的是,如果你想要一个有弹性的系统,你必须使用异步消息传递来进行服务通信,这样做的缺点是你必须像@qujck 所说的那样最终保持一致性,但它带来的好处比缺点。

      在您的用例中,当您调用服务 A 时。它应该创建一些记录来跟踪具有等待 B 和 C 状态的操作。然后,它应该使用带有事件持久性的某种消息代理(如 Kafka)向服务 B 和 C 发送命令(消息),以确保不会丢失任何消息。 如果此服务中的任何一个关闭,则没有问题,因为消息将保留在 kafka 中,直到服务启动并最终使用它。

      当这种情况发生时,每个服务都会发送一个事件(消息)说“我完成了”。服务 A 将侦听此消息,然后将操作状态更新为“等待 B”或 C,当两条消息都到达时,最终更新为“已完成”。

      如果由于任何其他原因服务 B 或 C 无法完成请求,它们将发送错误消息而不是完成消息,然后服务 A 将向其他服务发送命令请求回滚。如果这个服务宕机了也没关系,因为最终它会上升,读取回滚命令并执行它以确保没有任何不一致

      【讨论】:

        猜你喜欢
        • 2021-06-20
        • 2016-06-10
        • 2016-03-05
        • 2018-01-22
        • 1970-01-01
        • 2021-01-17
        • 2019-09-30
        • 2016-08-10
        • 2019-01-18
        相关资源
        最近更新 更多