19

我正在研究 rpc 语义,至少一次和最多一次语义,它们是如何工作的?

无法理解其实现的概念。

4

1 回答 1

51

在这两种情况下,目标都是调用该函数一次。但是,不同之处在于它们的故障模式。在“至少一次”中,系统将在失败时重试,直到它知道该函数已成功调用,而“最多一次”不会尝试重试(或将确保对在重试之前调用)。

至于这些是如何实现的,这可能会有所不同,但伪代码可能如下所示:

At least once:
    request_received = false
    while not request_received:
       send RPC
       wait for acknowledgement with timeout
       if acknowledgment received and acknowledgement.is_successful:
          request_received = true


At most once:
   request_sent = false
   while not request_sent:
      send RPC
      request_sent = true
      wait for acknowledgement with timeout
      if acknowledgment received and not acknowledgement.is_successful:
         request_sent = false

您想要执行“最多一次”的示例案例类似于付款(您不想意外地向某人的信用卡计费两次),其中“至少一次”的示例案例就像使用特定值更新数据库(如果您碰巧连续两次将相同的值写入数据库,那真的不会对任何事情产生任何影响)。您几乎总是希望对非变异(又名幂等)操作使用“至少一次”;相比之下,大多数变异操作(或至少是那些递增地改变状态并因此在应用变异时依赖于当前/先前状态的操作)将需要“最多一次”。

我应该补充一点,在“至少一次”系统之上实现“最多一次”语义是相当普遍的,方法是在 RPC 的主体中包含一个唯一标识它的标识符,并确保在服务器上看到每个 ID系统只处理一次。您可以将 TCP 数据包中的序列号(确保数据包按顺序交付一次)视为此模式的一个特例。然而,这种方法在分布式系统上正确实施可能会有些挑战,其中相同 RPC 的重试可能会到达运行相同服务器软件的两台独立计算机。(处理这个问题的一种技术是记录接收到 RPC 的事务,然后在系统内部重新分配请求以进行进一步处理之前,使用集中式系统对这些记录进行聚合和重复数据删除;另一种技术是机会性地处理 RPC,但在服务器之间的同步最终检测到这种重复时协调/恢复/回滚状态......这种方法可能不会用于支付,但它在其他情况下可能很有用,如论坛帖子) .

于 2012-11-11T10:06:56.807 回答