gpt4 book ai didi

rest - 跨 REST 微服务的事务?

转载 作者:行者123 更新时间:2023-12-02 18:06:10 25 4
gpt4 key购买 nike

假设我们有一个用户、钱包 REST 微服务和一个将事物粘合在一起的 API 网关。当 Bob 在我们的网站上注册时,我们的 API 网关需要通过 User 微服务创建用户,并通过 Wallet 微服务创建钱包。

现在这里有一些可能出现问题的场景:

  • 用户 Bob 创建失败:没关系,我们只是向 Bob 返回一条错误消息。我们使用 SQL 事务,因此没有人在系统中见过 Bob。一切都很好:)

  • 用户 Bob 已创建,但在创建钱包之前,我们的 API 网关严重崩溃。我们现在有一个没有钱包的用户(数据不一致)。

  • 用户 Bob 已创建,当我们创建钱包时,HTTP 连接断开。钱包创建可能成功,也可能失败。

有哪些解决方案可以防止这种数据不一致的情况发生?是否存在允许事务跨越多个 REST 请求的模式?我已阅读维基百科页面 Two-phase commit这似乎涉及到这个问题,但我不确定如何在实践中应用它。这个Atomic Distributed Transactions: a RESTful design尽管我还没读过,但这篇论文似乎也很有趣。

或者,我知道 REST 可能不适合这个用例。也许处理这种情况的正确方法是完全放弃 REST 并使用不同的通信协议(protocol)(例如消息队列系统)?或者我应该在我的应用程序代码中强制执行一致性(例如,通过后台作业来检测不一致并修复它们,或者通过在我的用户模型上设置具有“创建”、“创建”值等的“状态”属性)?

最佳答案

什么没有意义:

  • 使用 REST 服务进行分布式事务。根据定义,REST 服务是无状态的,因此它们不应该成为跨越多个服务的事务边界的参与者。您的用户注册用例场景是有意义的,但是使用 REST 微服务创建用户和钱包数据的设计并不好。

什么会让你头疼:

  • 具有分布式事务的 EJB。这是理论上行得通但在实践中行不通的事情之一。现在,我正在尝试使分布式事务适用于跨 JBoss EAP 6.3 实例的远程 EJB。我们已经与 RedHat 支持人员沟通了数周,但尚未奏效。
  • 一般两阶段提交解决方案。我认为2PC protocol是一个很棒的算法(很多年前我用 C 语言用 RPC 实现了它)。它需要全面的故障恢复机制,包括重试、状态存储库等。所有复杂性都隐藏在事务框架内(例如:JBoss Arjuna)。然而,2PC 并不能保证故障。在某些情况下,交易根本无法完成。然后您需要手动识别并修复数据库不一致问题。如果幸运的话,这种情况可能在一百万笔交易中发生一次,但也可能每 100 笔交易中发生一次,具体取决于您的平台和场景。
  • Sagas(补偿事务)。存在创建补偿操作的实现开销,以及最终激活补偿的协调机制。但补偿也不能证明失败。您可能仍然会遇到不一致的情况(=有些头痛)。

可能最好的选择是什么:

  • 最终一致性。类似 ACID 的分布式事务和补偿事务都不是防失败的,并且都可能导致不一致。最终的一致性往往比“偶尔的不一致”要好。有不同的设计解决方案,例如:
    • 您可以使用异步通信创建更强大的解决方案。在您的场景中,当 Bob 注册时,API 网关可以向 NewUser 队列发送一条消息,并立即回复用户说“您将收到一封电子邮件以确认帐户创建”。队列消费者服务可以处理消息,在单个事务中执行数据库更改,并将电子邮件发送给 Bob 以通知帐户创建。
    • 用户微服务在同一数据库中创建钱包记录。在这种情况下,用户微服务中的钱包存储是主钱包存储的副本,仅对钱包微服务可见。有一个基于触发器或定期启动的数据同步机制,将数据更改(例如新钱包)从副本发送到主服务器,反之亦然。

但是如果您需要同步响应怎么办?

  • 重构微服务。如果队列解决方案不起作用,因为服务使用者需要立即响应,那么我宁愿重构用户和钱包功能,将其并置在同一服务中(或至少在同一虚拟机中,以避免分布式事务) )。是的,它离微服务更远了一步,更接近于整体,但会让你免于一些头痛。

关于rest - 跨 REST 微服务的事务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30213456/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com