Rest 微服务体系结构中的分布式事务,如何处理超时和失败的提交

Rest 微服务体系结构中的分布式事务,如何处理超时和失败的提交,rest,rabbitmq,microservices,distributed-transactions,Rest,Rabbitmq,Microservices,Distributed Transactions,假设您有一个服务a,它是大型微服务体系结构的一部分,在这个体系结构中,这些服务通过REST API或涉及某个代理的消息传递(RabbitMQ)相互通信。服务A公开REST端点,该端点需要与某个第三方服务进行通信(与不在我们体系结构中的服务进行通信)并在那里创建一些内容,当服务A收到第三方的响应,表示那里一切正常时,它应该将该响应中的一些数据保存在自己的数据库中 考虑到第三方不提供任何幂等机制,覆盖以下问题的最佳方式是什么 第三方端的创建正常,但在服务A中DB write失败。这将导致不一致的状态

假设您有一个服务
a
,它是大型微服务体系结构的一部分,在这个体系结构中,这些服务通过REST API或涉及某个代理的消息传递(RabbitMQ)相互通信。服务
A
公开REST端点,该端点需要与某个第三方服务进行通信(与不在我们体系结构中的服务进行通信)并在那里创建一些内容,当服务
A
收到第三方的响应,表示那里一切正常时,它应该将该响应中的一些数据保存在自己的数据库中

考虑到第三方不提供任何幂等机制,覆盖以下问题的最佳方式是什么

  • 第三方端的创建正常,但在服务
    A
    中DB write失败。这将导致不一致的状态,您在第三方端创建了一些内容,但您自己的数据库中不需要关于它的数据

  • 您收到了来自第三方的超时,所以您不能重复呼叫,因为他们不提供任何幂等机制。如果重复调用,可能会以两个(或更多)创建的资源结束,而不是一个

  • 问题1。可以通过任何重试机制来解决,该机制可以重试DB调用任意次数。这种方法的问题在于,如果正在重复DB调用的服务
    实例突然停止

    据推测,更好的方法是在第三方成功创建服务后,发布一条关于成功创建的RabbitMQ消息。该服务将侦听该消息,并在收到该消息时执行DB调用。通过良好的重试机制和利用确认消息,可以解决以下问题:
    如果服务实例突然宕机怎么办
    因此,在这个解决方案中,服务是自己消息的发布者和消费者。还有更好的主意吗?此解决方案还将引入最终一致性,因为API调用者(调用服务
    A
    端点的人)将在第三方成功创建之后,但在服务数据库中保留任何内容之前(API客户机实际需要的内容)立即收到响应


    超时问题呢在这种情况下,如何处理来自第三方的超时?。我认为没有什么比发出GET调用来检查他们是否创建了一些东西更好的了。同样,GET调用可能会失败,但它可以重复,直到成功。这里还有一个边际用例,即如果服务在发出GET调用时停止,该怎么办。

    正确设置容错并不容易。我记得netflix堆栈实现了一个专用模块:。也许这会对您有所帮助。

    正确设置容错并不容易。我记得netflix堆栈实现了一个专用模块:。也许这会对你有帮助。

    你应该考虑删除分布式事务和2阶段提交。在云环境中或涉及第三方代码/基础设施时进行设置和处理是一场噩梦。2PC的替代方案是最终的一致性和补偿事务。@Bishoy我在这里使用或提出2PC的方式是什么?正如我所说的,至少在我看来,在这里我提出了一个包含代理和最终一致性的异步处理。您应该考虑删除分布式事务和2个阶段提交。在云环境中或涉及第三方代码/基础设施时进行设置和处理是一场噩梦。2PC的替代方案是最终的一致性和补偿事务。@Bishoy我在这里使用或提出2PC的方式是什么?正如我所说的,至少在我看来,这里我建议使用代理进行异步处理,并最终实现一致性。使用NServiceBus,我将使用名为saga的两个功能解决此场景,使用NServiceBus的outbox,我将使用名为saga和outbox的两个功能解决此场景