两个网络客户端之间的竞争条件

时间:2014-07-10 21:32:51

标签: networking distributed race-condition

我有以下问题:我有两个网络客户端,其中一个是要由其所有者“声明”的设备,另一个是声称它的程序。当受让人点击服务器时,它宣布它可以被索赔,然后请求者可以声明它(在认证和提供信息之后它只能知道当然)。但是,如果claimer首先击中服务器,那么我有一个经典的“丢失信号”问题。请求者可以重试,这很好,但我最终可能会遇到以下竞争条件,这是主要观点:

Claimee点击服务器并宣布,然后其连接失败 Claimer进来找到宣布的记录,并声称它 Claimee以无人认领的状态重新连接,并覆盖声明

我想到了一些解决方案:

1)60秒后,旧的claimee宣布过期,并让请求者重试。这仍然容易受到上述问题的影响,但会将窗口缩小到大约60秒。此外,claimee需要大约30-40秒的时间来进行自举,因此应该务实地使问题很难遇到或重现。

2)索赔人提出的索赔对索赔进入后30秒内的任何索赔人有效。这有效,但开始混淆了一个主张宣布的定义:这意味着申诉人宣布并非总是如此解释为“重置申请人身份”,因为在最后一次申请后最多30秒,这意味着“加入最后申请。”

这些是高点,但可能不足以描述问题,所以如果我可以添加任何评论以进一步阐明,请告诉我。就解决方案而言,这些是可行的解决方案,但我正在寻找一个已知问题的类比,并看看是否有我没有想到的想法。

1 个答案:

答案 0 :(得分:0)

也许我没有正确理解问题描述,但你还有另一个问题 - 如果两者连接得很好而且claimee失败怎么办?除非你假设这种情况永远不会发生,否则请求者也需要处理这个问题。

一般来说,有两种方法可以为这两个问题实现解决方案,但最可靠的方法可能会受到Java RMI使用的实现的启发。

当你向claimee发送消息时,添加一个唯一的ID。当您没有得到答案时,您可以使用相同的ID重复发送消息几次(消息可能会丢失),并且在一些更长的超时后,您可以接受该请求者不可用。现在,您可以再次在服务器上查找连接信息并重新启动该过程。

为此,您需要缓存尚未在claimer方面处理的所有消息。此外,在claimee方面,您需要缓存最后的X消息ID及其结果(如果可用)这是必要的,以便不会多次在一个消息中执行操作,并且还能够再次使用正确的结果进行回复(因为结果消息可能会丢失)