即时通讯应用背后的系统设计
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
我们每天都会使用 WhatsApp 和 Telegram 等即时通讯应用与朋友聊天。这些应用背后都蕴含着一些设计方案,这些方案直接影响着用户体验。本文将从用户的角度描述一些可见的功能,并解释其背后的技术细节。然而,本文并非完整的系统设计,还有许多值得深入探讨的主题。
消息传递状态
所有即时通讯软件都会显示消息状态。应用程序会向用户提供消息是否已发送、已送达以及是否已被收件人阅读的信息。WhatsApp 在这方面做得非常好。
它展示了信息传递过程中的几个阶段:
- 当用户点击“发送”按钮时,消息会从客户端设备发送到网络服务器(时钟图标)。
- 当消息到达服务器时,服务器会向客户端发送通知。此时,图标变为一个单独的勾号。
- 网络服务器会查找与接收方之间建立的连接,并发送消息。接收方客户端设备会向服务器发送通知,之后服务器可以向发送方发送通知,告知消息已送达,并且图标会发生变化以进行再次确认。
- 最终,收件人打开应用程序并阅读了消息。他的设备向服务器发送了一条通知,服务器随后通知发件人消息已被阅读。图标变为蓝色的双勾。
下图说明了这一过程,并为进一步的讨论引入了一些必要的设计模块。
这款即时通讯应用每天需要处理超过1000亿条消息,相当于每秒约100万条。为了应对如此巨大的负载,该应用采用了分布式架构,而负载均衡器(LB)正是其中的关键组件。负载均衡器通过特定的策略,将负载均衡到不同的服务器上。
Messenger 的目标是在用户和服务器之间快速传递消息。它使用 Web 套接字来实现这一点。Web 套接字是一种通过 TCP 连接提供双工通信的协议。与 HTTP 连接相比,维护 Web 套接字连接的成本更低。客户端和服务器相互订阅并等待新消息。这就是为什么示意图中的所有箭头都是双向的。
不同的用户可能连接到不同的 Web 服务器,因此我们需要 Web Socket 管理器。该服务负责提供有关连接的信息,并将消息路由到正确的 Web 服务器。
如果收件人离线,则应存储消息。数据库应针对频繁的写入和删除操作进行优化。删除操作应在客户端上线且所有消息都已送达后执行。NoSQL 数据库是此场景下的一个选择,例如,一些即时通讯软件使用 HBase 和 Cassandra 来解决此问题。
后台数据获取和强一致性
WebSocket 协议允许即时通讯应用长时间保持连接,即使用户当前不在线也能加载消息。移动应用通常会在后台运行,只要设备连接到网络,就能加载新消息。您可能注意到,通常在解锁手机并打开应用后,消息会立即显示。我们再来看看长时间关闭且没有任何后台进程的桌面客户端。
在这个录像中,应用程序仅在启动后才建立 WebSocket 连接。连接建立后,才会从服务器接收新消息。消息不是一次性加载,而是逐条加载。这引出了即时通讯系统设计的另一个重要要求:一致性。消息的顺序至关重要。如果接收者收到的消息顺序与原始顺序不一致,那将非常奇怪,而且消息也不能丢失。该应用程序的一致性在于严格按照顺序提供消息。CAP 定理指出,任何分布式数据存储只能提供以下三个特性中的两个:一致性、可用性和分区容错性。应用程序必须提供分区容错性,因此它们必须在一致性和可用性之间做出选择。即时通讯服务选择一致性而非可用性。这就是为什么我们在上图中看到,用户需要等待几秒钟才能加载聊天记录。
下载文件缓存
我们讨论了一些聊天方面的内容,但即时通讯软件也允许用户分享媒体文件。最后一点是关于优化网络带宽。文件显然比消息大,因此尽量减少用户上传和下载文件的次数非常重要。当用户上传文件时,服务器会存储该文件并计算一个唯一的校验和。如果用户上传的文件已存在于服务器上,应用程序会检查校验和以防止重复上传。从用户的角度来看,我们可以尝试重复以下步骤:
- 上传文件。我用 Telegram 的已保存消息来检查。
- 将其移除并清除设备缓存。
- 重新上传文件。
第一次和第二次上传尝试之间会有明显的差异,第二次上传几乎是立即完成的。
注意:重复文件检查速度可能取决于用户的地理位置。分布式系统在全球各地部署了大量服务器,因此响应时间(在讨论分布式系统设计时,我们通常使用“延迟”一词)实际上可能会更长。如果用户从与原始位置不同的地点上传重复文件,则可能需要更长时间,因为最近的服务器没有相关信息。
另一个值得一提的是内容分发网络(CDN)。CDN 用于存储静态内容,例如图像和视频。它们基于网络基础设施,可以将文件放置在地理位置上更靠近用户的位置。因此,内容分发速度更快,延迟更低。
结论
我们讨论了一些你在与朋友聊天时每天都会看到的即时通讯应用程序的功能,现在你可以更好地理解为我们提供这种用户体验的系统模块和设计决策。
感谢您抽出时间阅读本文。欢迎在评论区留下您的反馈意见,以及您最喜欢的应用功能和您想了解的内部原理!
文章来源:https://dev.to/titovmx/system-design-behind-a-messenger-app-2268





