系统设计:设计类似WhatsApp的应用

a645b6a854bcb55485148047b3de3fe5.png
1*mMcr7ZQNI7H3fWPBFAE-fg.png

在这个系统设计场景中,我们被要求设计一个类似WhatsApp的消息应用程序。

虽然在实际的讨论中可能会重点讨论该应用程序的一个或多个功能,但在本文中,我们将对系统的架构进行一个高层次的概述,然后可以根据需要深入探讨具体的领域。

明确功能需求

通过向业务方提问来缩小范围,因为在一个小时内设计整个WhatsApp平台是不现实的:

fff2ae1b1b244349b61f9170cdb77b90.png
1*JhQJNfkan7qHRs7PKY8ZuA.png

主要用例: 该应用的主要目的是发送、检查和接收消息,以及阅读和标记消息为已读。•群组: 我们将不涉及群组消息,只考虑一对一消息。•内容类型: 我们只支持文本消息,不支持图片或视频。

明确非功能需求

规模: 首先,我们来谈谈规模,即系统的大小和消息的处理量。假设每天发送100亿条消息,并且我们计划在一年内将其翻倍。

5e443a529dc252ed9e629cafefafd394.png
1*l358A_oZdxvNct33NsZXAQ.png

可用性: 在可用性方面,我们希望系统高度可用并始终运行。

延迟: 至于系统延迟,我们希望它几乎是即时的,因此大多数API请求应在100毫秒内完成。

估算:数据计算

每天100亿条消息,约为10B消息 / 86,400秒每天 = 115,740条消息每秒(MPS)。在一年内翻倍意味着我们应计划为115,740 * 2 = 231,480 MPS

假设每条消息200字节,每日存储量为10B消息 * 200字节 = 2 TB。年存储量及增长约为2TB * 365天 * 2 = 1.5 PB

05b55c963e0cfccb6ebc3401538ffd86.png
1*Z5S5qQ4ygdMuOPYgg3kh9A.png

需要注意的是,我们计算的是平均值,但系统需要处理高峰流量,这可能比平均MPS高得多。我们可能需要根据高峰时间进行扩展。

接口API设计

我们可能会使用RESTful API风格以获得更广泛的兼容性。以下是可能的端点细分:

1.发送消息 (POST /messages): 请求体包括接收者的ID和消息内容。成功响应(200)返回唯一的消息标识符。错误代码(400, 500)处理缺少参数或服务器问题。2.检查新消息 (GET /messages): 响应为包含未读消息的数组(200)或如果没有则返回204。3.获取特定消息 (GET /messages/:messageId): 返回特定消息(200)或未找到则返回404。4.标记消息为已读 (PUT或PATCH /messages/:messageId): 成功响应(200)确认更改,而404表示未找到消息。

75f9770e0a88142b079d6c1dea3e16ef.png
1*inhUO4uebAQAAtJ7Yg42Aw.png

其他考虑: 我们将集成WebSockets以实现实时更新。API将处理认证和初始连接建立。并且分页可能是‘检查新消息’端点所需的。安全措施,如输入验证,也是必要的。

系统设计

移动应用: 用户的主要界面将是移动应用(iOS, Android)。此应用程序处理发送和接收消息、联系人管理和对话。

负载均衡器: 为了有效处理传入请求,我们将使用负载均衡器来分配流量到多个服务器。这样可以提高应用程序的可靠性。

067a768841ec0df189b728977cb44125.png
1*QQ_mTtf5AL4HM7kWFlNFew.png

API服务器: 所有请求将进入API服务器,这些服务器处理我们之前概述的RESTful API,管理消息逻辑。API服务器本身可以是无状态的,这样我们可以水平扩展(添加更多服务器)以应对流量增长。

WebSocket连接: 类似WhatsApp的应用程序严重依赖WebSockets进行实时通信。聊天服务器将与移动应用程序保持持久的WebSocket连接。当消息到达时,可以立即推送到接收者的设备。

消息分发器: 接下来,我们将有一个消息分发器服务,该服务的主要目的是将API服务器与直接数据库写入解耦,这对于处理高写入量尤其重要。

27aa8d54aa526c0fe26dd43e33887c73.png
1*UbP77kPYrJLtTk2GgtU2yQ.png

消息队列,如Kafka或RabbitMQ,是这里的理想选择。其工作原理如下:

1.API服务器接收到“发送消息”的POST请求。2.它将消息放在队列中,并迅速向客户端返回成功/确认。3.独立的工作进程异步从队列中读取并将消息写入数据库。

数据库 (NoSQL): 我们同意最终一致性是可以接受的,这使得NoSQL成为高消息量的可扩展选择。

以下是两个强有力的选择:

Cassandra: 以可扩展性、高可用性和写性能而闻名的宽列存储。特别适合我们预期的高写入量和简单读取模式(主要通过ID获取消息)。•DynamoDB: AWS提供的完全托管的键值和文档数据库。如果我们想要一个最小维护的数据库解决方案且能轻松扩展,这非常有利。

96dad623633cd4d89fdb8042fdc52e53.png
1*cilep-C-F6E3mvKskRv2uw.png

分片和分区: 由于没有单一数据库可以处理我们1.5 PB的存储需求,因此分片(水平分区)数据是至关重要的。

但是我们将如何分片和分区这些数据,以及这些API服务器如何知道从哪里请求这些数据?

005ec766bfef2c4db7c010061fc0047d.png
1*MMsvLcumh4AFFqOAldO_Nw.png

我们可以基于userId进行分区。所有涉及用户的消息将驻留在同一个分片/分区中。而我们的API服务器有两种可能的方法来定位数据:

896e06878cf0d2b38fb4dfa616191cba.png
1*pXng7Ti6Xcuqsgun4ZcgPA.png

一致性哈希环: 数据位置可以基于分区键确定,允许API服务器直接路由请求到正确的数据库分片。•元数据服务: 一个独立的服务保持分区键到分片位置的映射。API服务器首先查询此服务,然后进行数据库调用。

结论和当前系统瓶颈

这概述了类似WhatsApp应用程序的主要架构。现在,让我们看看我们当前系统中的潜在瓶颈和改进领域:

数据库写入: 高写入量是一个潜在的瓶颈。分片、消息队列和优化的数据库选择是关键。•端到端加密: WhatsApp模型非常强调安全性。实现端到端加密将是一个关键讨论点。•群组聊天: 此功能为消息路由和存储带来了额外的复杂性。•媒体处理: 我们可以实现一个处理图像和视频上传的系统,这里使用压缩以及多种存储大小的缩略图。

  • 12
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小技术君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值