好的,首先,您无法通过不可靠的链接保证任何事情。两位将军的问题对确定性和非确定性协议都证明了这一点。您所能做的就是将不可靠性降低到可接受的程度。
在您的情况下,最简单的方法是,一旦服务器收到轮询请求,它就会发送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 非常可靠)。