我正在做系统设计面试准备,并且正在练习“设计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;在设计消息传递应用程序时,似乎有序消息传递定义了一个部分顺序,它需要每个用户队列(用于按顺序传递消息)和每个组队列(用于以相同顺序将消息放在每个收件人的队列中) .