1

我正在做系统设计面试准备,并且正在练习“设计WhatsApp”问题。我仍然不清楚的一件事是像 WhatsApp 这样的系统如何维持消息传递的顺序。我将给出我的高级理解:

消息传递需要是因果的,但不需要是可线性化的。也就是说,并发消息(其中并发定义为“键入”和“服务器确认”之间的消息)是无与伦比的,可以按任何顺序传递。

排序/因果关系可以应用于组内消息(最突出的情况)或组间消息(例如,如果两个用户是与其他用户的两个不同共享聊天的一部分)。

我见过的大多数设计要么没有明确解决有序消息传递,要么使用每个用户的消息队列来解决它(例如,https ://www.youtube.com/watch?v=WzBzYX1aSrU&t=0s )。这个每用户队列可以是服务器上的队列(例如,RabbitMQ),也可以是类似于以 user_id 作为消息组 id 的 FIFO SQS 队列(尽管 SQS 方法可能无法扩展给定 FIFO SQS 约束)。但是,我不清楚每用户队列如何完全解决消息排序问题。每个用户的队列确保消息的有序传递,但不确保消息以正确的顺序放置在给定用户的队列中。

我可以想到两种主要的方法来避免这种情况。一种是按组分配消息工作者。然后我们有一个架构,其中为每个用户分配了一个网关来处理该用户/客户端的消息(发送和接收 - Gaurav Sen 在https://www.youtube.com/watch?v=vvhC64hQZMk中讨论了这种方法) . 对于每个组,分配有一个消息处理器来处理该组的消息。这样,消息处理器将在处理另一条消息之前将给定消息推送到每个用户的网关队列(或者如果该用户离线,则推送到临时存储)。

解决这个问题的另一种方法是全序广播(尽管也许可以使用某种全序多播)。但是,我不一定看到这将如何扩展,因为尚不清楚多播是否会起作用(并且广播似乎不会扩展)。

TLDR;在设计消息传递应用程序时,似乎有序消息传递定义了一个部分顺序,它需要每个用户队列(用于按顺序传递消息)和每个组队列(用于以相同顺序将消息放在每个收件人的队列中) .

4

1 回答 1

2

我不知道 WhatsApp 是如何工作的,但关于您的问题:

我仍然不清楚的一件事是像 WhatsApp 这样的系统如何维持消息传递的顺序

您讨论的一种方法是队列和消息管理。

另一个是时间。使用时间戳(例如 UTC),系统可以看到消息在时间方面的关系(例如,当它们第一次到达后端时),因此它们应该如何显示,基于时间戳。想象一下,客户分批提取存在的任何消息,您无需担心获得正确的订单,因为消费者只需处理公共时间戳即可。

请记住(除非他们使用一些自定义网络)应用程序将在互联网上使用 HTTPS;保持连续连接(如 WebSocket)是可能的,但我假设大多数使用遵循 HTTP,它是基于请求/响应的——这意味着客户端向服务器询问信息——服务器无法在未经请求的情况下将其推送出去。

回到时间戳,在这种方法中,后端/服务器系统可以向客户端软件提供他们当时拥有的任何和所有消息,并且他们知道他们不需要担心处理消息顺序,因为整个系统设计基于时间戳将该责任委托给客户端。这种方法的一个潜在优势是简单 - 无需管理消息排序以及随之而来的复杂性。

关于这一点:

但是,我不清楚每用户队列如何完全解决消息排序问题。每个用户的队列确保消息的有序传递,但不确保消息以正确的顺序放置在给定用户的队列中。

用户队列完全有可能与交付有关,与正确的排序无关。作为一般规则,系统的某些部分应该只有一项工作,而且它们做得非常好。这通常会带来更好的设计:更容易维护,操作更可靠。

于 2021-08-08T22:12:03.820 回答