分布式系统中的两位将军问题是什么?

网络可靠性是人们对专注于网络行为的分布式系统的错误认识之一。

在设计大型应用程序时,我们经常假设在两个节点之间通信时会丢失一些消息。这种消息丢失可能由于多种原因而发生:电源故障、电缆切断、节点故障、网络拥塞等,俗称网络分区

系统实体通常会重新发送可重试错误或超时的请求,直到收到确认,以提高系统的可靠性并降低丢失消息的百分比。

这种方法使我们能够确认接收方已收到消息,但是,这种重试会发生幂等一致性问题。总体上这个问题属于CAP定律问题

在本文中,我们将只了解两将军问题,也就是着重阐述网络不可靠本身这个问题,它类似于通过网络在任意两个节点之间进行通信。

两位将军的问题
两位将军问题是一个思想实验,旨在了解网络在分布式系统中的行为方式。

  • 想象两位将军,各自率领一支军队。他们都想占领一座城市。
  • 唯一能占领这座城市的场景是两支军队同时进攻。
  • 如果只有其中一支军队进攻,他们就会被击败。

二者位于城市的不同一侧,为了沟通和协调进攻计划,双方的信使都需要经过城市,而城市则可以将他们抓获。因此,一位将军发出的消息可能会被另一位将军收到,也可能不会,因为城市可以抓获携带消息的信使。除此之外,消息的发送者不会知道接收者将军是否收到了消息,直到接收者将军向发送者发回确认消息。

然而,可能会出现这样一种情况:

  • 原始消息已传递给接收者,但确认丢失了。
简而言之,当接收者没有收到消息时,无法判断是发送者没有发送消息还是城市抓获了信使。

分布式系统中的网络行为
在分布式系统世界中,两位将军可以映射到两个节点,而城市可以映射到两个节点用于相互通信的网络。这个关于两将军问题的思想实验指出,无论两个节点交换多少消息,他们永远无法百分之百地确定彼此的状态。

在实际实施中,会放宽某些限制以使系统正常运行,并采取措施在一定程度上解决任何消息丢失问题。例如,在由游戏电子商务商店和支付网关服务组成的系统中,要完成购买,付款应该成功,并且应该发送游戏下载链接。可能会出现支付服务和电子商务服务之间的通信中断,从而导致消息丢失的情况。可能出现以下情况:

  • 客户已付款,但由于付款确认丢失,游戏下载链接未发送
  • 客户已付款,收到付款确认,但由于某些服务故障,未发送游戏下载链接

在第一种情况下,电子商务服务可以重试查询支付服务以确保付款已处理。
在第二种情况下,客户可以退款。

在这两种情况下,我们都放宽了限制(并增加了重试次数的上限),允许服务的操作被撤消(付款被退款)或重试(电子商务商店查询支付服务)。这些措施使系统能够正常工作,因为除非出现严重的网络问题或网络分区,否则分布式系统中不太可能丢失所有消息。