• 如何设计实时聊天系统的架构


    请添加图片描述

    1. 系统的要求和目标

    1.1 功能要求

    • 对话:系统应支持用户之间的一对一和群组对话。
    • 确认消息:系统应支持消息传递确认,如已发送、已送达、已读。
    • 共享:系统应支持媒体文件的共享,例如图像、视频和音频。
    • 聊天存储:系统必须支持用户离线时聊天消息的持久存储,直到消息成功传递。
    • 推送通知:一旦离线用户的状态变为在线,系统应该能够向其通知新消息。

    1.2 非功能性需求

    • 低延迟:用户应该能够以低延迟接收消息。
    • 一致性:消息应该按照发送的顺序传递。此外,用户必须在所有设备上看到相同的聊天历史记录。
    • 可用性:系统应该具有高可用性。然而,一致性比可用性更重要。
    • 安全性:系统必须通过端到端加密来保证安全。我们需要确保只有通信双方才能看到消息的内容。中间的任何人,甚至我们作为服务所有者,都不应有权访问。
    • 可扩展性:系统应该具有高度可扩展性,以支持每天不断增加的用户和消息数量。

    2. 高层系统设计

    2.1 通讯方式

    首先,我们需要了解客户端和服务器如何通信。在聊天系统中,客户端可以是移动应用程序或 Web 应用程序。客户端之间不直接通信。每个客户端都连接到一个聊天服务,该服务支持我们之前讨论的所有功能:

    • 接收来自其他客户端的消息。
    • 为每条消息找到正确的收件人,并将消息转发(传递)给收件人。
    • 如果收件人不在线,则需要在服务器上保留该收件人的消息,直到他们在线为止。

    由于 HTTP 是客户端发起的,我们无法真正从服务器向接收者发送消息,因此我们需要考虑用于模拟服务器发起的连接的其他技术:轮询、长轮询和 WebSocket。

    • 轮询:是客户端定期向服务器请求数据,产生大量请求,效率低下。
    • 长轮询:服务器保持连接打开,直到有新数据可用,从而减少请求数量和延迟。
    • WebSocket:是一种双向通信协议,可通过单个长期连接实现客户端和服务器之间的实时通信,从而提供最低的延迟。它是从服务器向客户端发送异步更新的最常见解决方案。

    两个客户端之间的通信步骤如下:

    1. 用户A和用户B创建与聊天服务器的通信通道。
    2. 用户A向聊天服务器发送消息。
    3. 当收到消息时,聊天服务器会向用户 A 回复确认消息。
    4. 如果接收者的状态为离线,则聊天服务器将消息发送给用户B,并将消息存储在数据库中。
    5. 用户 B 向聊天服务器发送确认消息。
    6. 聊天服务器通知用户A消息已成功发送。
    7. 当用户 B 阅读消息时,应用程序通知聊天服务器。
    8. 聊天服务器通知用户A用户B已阅读消息。

    对于客户端-服务器聊天通信,WebSocket 优于 HTTP(S) 协议,因为 HTTP(S) 不会保持连接打开以供服务器频繁向客户端发送数据。使用 HTTP(S) 协议时,客户端不断向服务器请求更新,这会占用大量资源并导致延迟。WebSocket 在客户端和服务器之间维护持久连接。只要数据可用,该协议就会立即将数据传输到客户端。它提供了双向连接,用作将异步更新从服务器发送到客户端的通用解决方案。
    其他一切非聊天内容不一定都是通过 WebSocket协议。事实上,聊天应用程序的大多数功能(注册、登录、用户配置文件等)都可以使用基于 HTTP 的传统请求/响应方法。

    2.2 高级组件

    聊天系统分为三大类:无状态服务、有状态服务、第三方集成。

    • 无状态服务:是传统的基于HTTP的请求/响应服务,用于管理登录、注册、用户配置文件等。它们位于负载均衡服务后面,负载均衡服务的工作是根据请求路径将请求路由到正确的服务。这些服务可以是整体的或单独的微服务。我们不需要自己构建许多无状态服务,因为市场上有可以轻松集成的服务。我们将深入讨论的一项服务是服务发现。它的主要工作是向客户端提供客户端可以连接的聊天服务器的 DNS 主机名列表。
    • 有状态服务:唯一有状态的服务是聊天服务。该服务是有状态的,因为每个客户端都维护与聊天服务器的持久网络连接。在此服务中,只要服务器仍然可用,客户端通常不会切换到另一个聊天服务器。服务发现与聊天服务密切配合,以避免服务器过载。
    • 第三方集成:用于推送通知,以便在新消息到达时通知用户,即使应用程序未运行也是如此。

    2.3 存储

    我们需要考虑使用哪种类型的数据库:关系数据库还是NoSQL。在典型的聊天系统中,我们将有两种类型的数据。
    第一个是通用数据,例如用户个人资料、设置和用户好友列表。这些数据应该存储在可靠的关系数据库中。我们需要实现复制和分片来满足可用性和可扩展性要求。
    第二个是聊天系统特有的:聊天历史数据。

  • 相关阅读:
    LinkedIn领英开发客户方法大全(篇二)
    【CPP】指针
    敏捷开发流程图Scrum
    【Spring Boot自动装配】
    【无标题】
    Mysql-主从复制与读写分离
    优化类问题概述
    每日一博 - Code如何被发布到生产环境
    win10系统如何分区硬盘,win10如何进行磁盘分区
    【牛客面试必刷TOP101】Day18.BM14 链表的奇偶重排和BM16 删除有序链表中重复的元素-II
  • 原文地址:https://blog.csdn.net/guohuang/article/details/133984802