跨服务交易或原子性

问题描述 投票:0回答:1

我有一个实时程序,使网络调用服务A采取有状态操作和网络调用服务B来记录该操作的历史记录。扭曲是:

  1. 如果B失败,我们必须恢复行动A(出于“原因”,我们需要一个完整的历史记录,否则行动根本不会发生)。换句话说,我们不能写一个审计跟踪,除非我们已经明确地成功地调用了服务来采取行动(即我们不能改变命令来首先调用审计跟踪,然后调用服务)。
  2. B中的历史记录无效,我们不能拥有(这是A的有状态方面)

我有一些想法,没有一个是理想的:

  • 在采取行动之前获取A的状态(这是一种可用的方法),如果对B的调用失败,我们可以再次使用原始状态调用第一个服务。接近的问题是,对A的“恢复”调用也可能失败。
  • 在高级别,这似乎可以通过服务级别的“事务”来解决(其中两个服务调用都成功或两者都失败)。主要算法似乎是2-phase commit,但它似乎不是我们可以使用的东西,因为我们没有我们正在调用的服务,所以不能保证稳定的存储,我们不能添加它的功能“同意“与”交易协调员“
  • 在我们这边实施我们自己的尽力模仿交易。在我看来,这是一个相当复杂的方法,很难或不可能正确
  • 有能力进入“最终一致的状态”。但是,根据2,某些排序是不可能的,因此我们必须等待所有排队的操作才能继续。这将使我们的服务可能不是实时的

有没有解决方案,我们可以完整的日志镜像满足要求,100%的正确性?

transactions atomic distributed-computing soa distributed
1个回答
1
投票

你没有提到所有服务正在进行通信的协议,为了这个答案,我假设是HTTP。

就像你说的那样,你的可能解决方案听起来不像是适合你。

  1. 在状态检查之前或之后服务改变状态太容易了,就像你说之后的任何补救措施也很容易失败。
  2. 我认为在这个场景中你已经概述了两阶段提交是不可能的。即使您拥有所有服务,但只使用HTTP也很难做到这一点。
  3. 我同意
  4. 在所有选项中,这个有腿。这完全取决于您对“实时”的要求。每当有人这么说我问'你的意思是什么?'什么都不是'实时'一切都需要一些时间来处理。总是会有一段时间来自某人,或某事要求做些什么来实际完成!毫秒秒和分钟之间的差异只是一个问题或要求,你需要花多少钱。

所以你说通过HTTP调用你的服务(让我们称之为X)通过HTTP再次调用两个服务A和B。如果你同时有很多对X的调用,那么就没有办法(或者至少很难)确保对A的调用顺序导致与B的调用顺序相同。但这又取决于你的要求和什么系统正在做什么,怎么样,也许每天只有一次呼叫你的系统?

我个人会建议使用队列,并转向事件驱动的架构。即使拥有最终一致的系统,您也可以让它运行得很热,并获得您想要的“实时”,这将花费您更多!

我希望这对你有用。我很想听听你对我的建议的看法。

© www.soinside.com 2019 - 2024. All rights reserved.