1.场景需求界定
在本章中,我们探讨聊天系统(应用)的设计。几乎所有人都用过聊天应用。图-1展示了市面上一些最流行的聊天应用。图-1
不同人可能想要不同的聊天应用。弄清楚准确的需求是非常重要的。举个例子,如果面试官想要的是一对一聊天系统,你就不要考虑如何设计一个主要用于群聊的系统了。
在本章中,我们会专注于设计一个像Facebook Messenger那样的聊天应用,它主要提供以下功能:
•一对一聊天,消息的传输延时低。
•小型群组聊天(最多100人)。
•展示在线状态。
•支持多设备,即同一个账号可以同时在多个设备上登录。
•推送通知。
我们设计的这个聊天应用可支持5000万DAU。
2. 顶层设计
为了设计出高水平的应用,你应该掌握关于客户端和服务器通信的基本知识。在聊天系统中,客户端可以是移动应用或网页应用。客户端之间不直接通信。每个客户端会连接到一个聊天服务。我们先关注基本操作。聊天服务必须支持下面的功能:•接收来自其他客户端的消息。
•为每条消息找到正确的接收者并将消息发过去。
•如果接收者不在线,则在服务器上先暂时保存这个消息,直到该接收者上线。
图-2展示了客户端(发送者和接收者)和聊天服务之间的关系。
图-2
当一个客户端想要开始一个对话时,它会使用一种或者多种网络协议连接到聊天服务。对于聊天服务来说,网络协议的选择是很重要的,最好和面试官一起讨论一下这个问题。
对于大部分客户端/服务器应用来说,请求是先从客户端发起的。聊天应用的发送者端也是如此。在图-2中,当发送者通过聊天服务发送一条消息给接收者时,它使用的是经过时间验证的HTTP协议。HTTP协议是最常见的网络协议。在这个场景下,客户端打开了一个到聊天服务的HTTP连接并发送消息,聊天服务把消息发给接收者。保持请求头是一种高效的方式,因为它使客户端和聊天服务之间保持持久的连接,同时也减少了TCP握手的次数。在发送者端,HTTP协议也是一个不错的选择,很多流行的聊天应用如Facebook Messenger一开始都是使用HTTP协议来发送消息的。
然而,接收者端要复杂一些。因为HTTP请求是客户端发起的,从服务器端发送消息并不容易。近年来,很多技术被用于模拟服务器发起连接,包括轮询(Polling)、长轮询(Long Polling)和WebSocket。这些重要的技术在系统设计面试中经常被问到,下面我们分别介绍它们。
2.1 轮询
如图12-3所示,轮询是一种客户端周期性询问服务器是否有新消息的技术。轮询的开销可能很大,这取决于轮询的频率。它可能会耗费宝贵的服务器资源来回答一个在大部分时间中答案都是“没有新消息”的问题。图-3
2.2 长轮询
轮询的效率较低,长轮询有时是更好的选择(见图-4)。图-4
在长轮询中,客户端保持连接处于打开状态,直到有新消息可用或者达到超时阈值。一旦客户端收到新消息,它就会立刻将另一个请求发送给服务器,重新开始这个流程。不过,长轮询有一些缺点。
•发送者和接收者可能并没有连接到同一个聊天服务器。基于HTTP协议的服务器通常是无状态的。如果使用Round Robin的方式来做负载均衡,接收到消息的服务器可能并没有与等待接收消息的客户端保持长轮询连接。•服务器没有好的方法来判断客户端有没有断开连接。
•效率不高。如果一个用户并不经常聊天,长轮询依然会在超时之后周期性地建立连接。
标签:场景,HTTP,轮询,接收者,面试,聊天,服务器,客户端 From: https://blog.csdn.net/launch2020/article/details/144926040