0

这建立在如何在公司之间发送消息。如果我决定公司 S(供应商)应该以一些简单的基于 HTTP 的方式轮询公司(B)的订单,那么最好的实现是什么。

  • 我假设 B 公司有一个正在运行的 Web 服务器,并且该 Web 服务器的后端数据库是持久的。我们应该尽可能少地假设 S 的存储过程以及它们是否能够保持状态(例如,已传输的 GUID 列表)
  • B 和 S 之间的 Internet 连接不可靠。
  • 我们必须在某个时间点达到最终一致性,这意味着 B 和 S 之间的所有订单都应该被转移。

实施这样一个系统的最佳实践是什么?

4

5 回答 5

3

解决此类问题的一种方法是使用某种排队产品,作为 IBM 人员,我立即考虑使用 MQ。但是,由于我本人实际上并不是 MQ 人,因此我可能会对您采用的基于服务的方法感到满意。

我想到了两种可能的方法。一种是使用WS Reliable Messaging,它将可靠性问题推到 Web 服务基础架构中。另一种是在简单但不可靠的服务之上手动启动您自己的可靠协议。

我没有用 WS Reliable Messaging 实现系统的实际经验,我确实相信它可以工作,但它确实需要对参与者进行一定程度的控制——因为它是一个相对较新的标准,我们不能保证任何给定的 IT 商店都将有一个实现,并且供应商之间的互操作性可能是一个问题。我对每一端的 SW 堆栈的控制越多,我就越倾向于使用 WS Reliable Messaging。[我也应该提到 WS Atomic Transaction,它也可以用来构建可靠的服务,同样的互操作问题也适用。]

那么自己动手呢?这里的关键是使所有服务具有幂等性。由于我们没有跨越两个系统的事务保证,我们必须假设任何给定的服务调用都可能失败,结果未知。

我将假设 B 想要确认 S 已接受订单,因此我们需要在订单转移时更新 B 和 S 的信息。

B 必须提供以下服务:

 Give me the next order(s)

 I have stored {orders ...}

那么我们如何定义“下一个”。如果我们正在处理的卷可以让我们拥有一个传输“线程”,那么最简单的情况就可以很好地工作。然后 B 正在逐个打勾发送的订单,并且订单的 ID 单调递增。然后我们可以简化为:

 I have stored order <65,004> please give me the next

请注意,这是一个幂等请求:它可以安全地重复多次。另请注意,S 必须预测两次获得相同订单的可能性,并检查是否有重复。

于 2010-10-27T06:55:30.443 回答
1

您可能正在寻找的是两阶段提交。它在互联网上有很好的描述,例如:

http://en.wikipedia.org/wiki/Two-phase_commit_protocol

它的要点:

提交过程如下:

* Phase 1
      o Each participating resource manager coordinates local 
        operations and forces all log records out:
      o If successful, respond "OK"
      o If unsuccessful, either allow a time-out or respond "OOPS" 
* Phase 2
      o If all participants respond "OK":
            * Coordinator instructs participating resource managers to "COMMIT"
            * Participants complete operation writing the log record
              for the commit 
      o Otherwise:
            * Coordinator instructs participating resource managers to "ROLLBACK"
            * Participants complete their respective local undos 

应该适用于任何类型的数据。

于 2010-11-02T21:25:22.037 回答
1

好的,首先,您无法通过不可靠的链接保证任何事情。两位将军的问题对确定性和非确定性协议都证明了这一点。您所能做的就是将不可靠性降低到可接受的程度。

在您的情况下,最简单的方法是,一旦服务器收到轮询请求,它就会发送x多个回复,所有回复都具有相同的GUID. 例如。

S: B, anything new?
S: B, anything new?
S: B, anything new?
B: Yes, S, I need a jacket (order #123).
S: B, anything new?
B: Yes, S, I need a jacket (order #123).
S: B, anything new?
B: Yes, S, I need a jacket (order #123).
S: B, anything new?
B: Yes, S, I need a jacket (order #123).
B: Yes, S, I need some shoes (order #124).
S: B, anything new?
B: Yes, S, I need a jacket (order #123).
B: Yes, S, I need some shoes (order #124).
S: B, anything new?
B: Yes, S, I need some shoes (order #124).
S: B, anything new?
B: Yes, S, I need some shoes (order #124).
...

S可能会收到订单的垃圾邮件,但由于每个请求都会发送 #,所以这没什么大不了的。如果我们以前错过了它,我们现在得到它。如果我们之前没有得到它,哇哦!我们现在有了。系统有效!您会注意到在我的示例中B发送消息的次数。5在现实场景中,您可能会发送数百或数千次消息,直到您获得所需的可靠性。

现在上述解决方案是处理和带宽密集型的,但它确实有效。一个更聪明的方法是做 TCP 所做的事情:进行三次握手。

S: Hello B. Are you there? -> SYN
B: Hello S, yep I'm here. What's up? -> SYN+ACK
S: Oh good, you're there. -> ACK
S: B, anything new?
B: Yes, S, I need a jacket (order #123).

但是.. HTTP 已经这样做了。因此,如果某事没有到达某个地方,您就会知道。连接超时、连接中断等。

现在,您可以在应用程序级别重新编写这些场景(输入 WS-ReliableMessaging),但实际上 TCP 已经是可靠的了。对这些 SOAP(ish) 框架和虚假协议(它们通常在 HTTP 之上工作)的一些批评者指责它们本质上是在更高的抽象层次上重新发明了轮子——以及轮子的问题。

底线是任何系统都可能发生故障,包括可靠的消息传递系统。

就最终一致性而言,我认为您可能会感到困惑。最终一致性仅适用于在 a 之后的分布式存储系统,您可能在一段时间内Write()无法确定性地检索它。Read()这似乎根本不是你的问题。我的意思是,我明白你在说什么,但在一个eventually consistent系统中,节点之间假设有一个可靠(足够)的连接。您没有做出这种假设(即使我认为您应该.. TCP 非常可靠)。

于 2010-11-03T01:14:38.337 回答
1

建立在迪娜提到的基础上。Webservices 将是上述问题的完美解决方案。可以商定一些协议来定义记录的数量。

S ---> D ( Call a service which would list record keys)
D----> S ( provide xml of keys)
S----> D ( Request each of the records)
D----> S ( Submit record)

如果在同步后创建了新记录条目,Destination 可以调用在源处部署的服务,该服务将处理新记录。

由于通信是通过购买 Web 服务引擎来处理的,因此您不必担心消息参数。可以添加 SSL 以确保安全。

干杯!

于 2010-11-09T16:53:26.117 回答
1

我想你是想说 B 公司是被动的参与者。S(供应商)只需要能够获得 B 发布的所有订单(最终一致性)。但是 B 不需要也不关心 S 已经有什么订单(不需要提交)。

如果公司 B 有一个半准确的时钟,您可以使用日期作为单调递增的 GUID,具体取决于事件的分辨率——如果您需要毫秒分辨率,您不会想要轮询。您只使用 B 的时钟,因此您不必担心同步问题。如果 B 发布了所有订单,则 S 可以从上次停止的地方继续接单。

我不确定您是否指的是易于实施的系统的最佳实践或最佳权衡。根据音量和响应时间,如果您无论如何都要进行轮询,则无需将其设为动态系统。将订单作为文本文件(以时间戳命名)转储到以日期命名的目录中,并将它们全部拉下(或有选择地)。您甚至可以按小时或任何有意义的方式将它们存储在目录中。HTTP GET 是幂等的。

这可能很难看,但听起来您并不期望 B 公司有太多复杂性。使用 SSL 和身份验证,它被锁定和加密。

如果您不需要性能,那么简单没有错。您真正从复杂的协议中获得了什么?

于 2010-11-09T21:10:47.813 回答