【发布时间】:2015-07-24 15:50:33
【问题描述】:
假设我们有一个用户、钱包 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 并使用不同的通信协议(如消息队列系统)吗?或者我应该在我的应用程序代码中强制执行一致性(例如,通过有一个后台作业来检测不一致并修复它们,或者在我的用户模型上使用“创建”、“创建”值等的“状态”属性)?
【问题讨论】:
-
如果用户没有钱包就没有意义,为什么要为其创建单独的微服务?最初的架构可能有问题吗?为什么需要通用 API 网关,顺便说一句?有什么具体原因吗?
-
@VladislavRastrusny 这是一个虚构的例子,但您可以将钱包服务视为由 Stripe 处理。
-
您可以使用流程管理器来跟踪事务(流程管理器模式)或让每个微服务知道如何触发回滚(传奇管理器模式)或执行某种两阶段提交 (blog.aspiresys.com/software-product-engineering/producteering/… )
-
@OlivierLalonde - 快进到 2019 年......你最终是如何处理这个问题的?最好的方法/解决方案是什么?如果你能写出这个好问题的答案会很有帮助。
标签: rest architecture transactions microservices