您当前的位置:首页 > 电脑百科 > 程序开发 > 架构

听说你会架构设计?来,弄一个微信群聊系统

时间:2023-11-02 11:37:18  来源:微信公众号  作者:xin猿意码

1. 引言

当我那天拿着手机,正在和朋友们的微信群里畅聊着八卦新闻和即将到来的周末计划时,忽然一条带着喜意的消息扑面而来,消息正中间写着八个大字:恭喜发财,大吉大利。

听说你会架构设计?来,弄一个微信群聊系统图片

抢红包!!相信大部分人对此都不陌生,那微信的这个群聊系统是如何设计的,让我们可以方便地聊天、分享图片和表情,还有那个神奇的红包功能呢?

这个问题一直困扰着,于是我决定深入了解一下,看看微信的群聊系统背后的设计是怎样的。

 

微信群聊系统设计

微信作为 10 亿用户级别的全民 App,想必大家都用过,微信建群功能是微信里面核心的一个能力,它可以将数百个好友或陌生人放进一个群空间。

听说你会架构设计?来,弄一个微信群聊系统图片

或许你已经在微信上体验过很多次群组聊天,但你是否好奇过这个背后的系统是如何设计的呢?

今天我们就来探讨一下。

 

2. 系统需求

2.1 系统特点与功能需求

微信群聊功能是社交应用的核心功能之一,它允许用户创建自己的社交圈子,与家人、朋友或共同兴趣爱好者进行友好地交流。

以下是微信群聊系统的核心功能:

听说你会架构设计?来,弄一个微信群聊系统图片

  • 创建群聊:用户可以创建新的聊天群组,邀请其他好友用户加入或与陌生人面对面建群。
  • 群组管理:群主和管理员能够管理群成员,设置规则和权限。
  • 消息发送和接收:允许群成员发送文本、图片、音频、视频等多种类型的消息,并推送给所有群成员。
  • 实时通信:消息应该能够快速传递,确保实时互动。
  • 抢红包:用户在群聊中发送任意个数和金额的红包,群成员可以抢到随机金额的红包。

 

2.2 非功能需求:应对高并发、高性能、海量存储

当我们面对 10 亿微信用户每天都可能使用建群功能的情景时,就需要处理大规模的用户并发。这就引出了系统的非功能需求,包括:

  • 高并发:系统需要支持大量用户同时创建和使用群组,以确保无延迟的用户体验。
  • 高性能:快速消息传递、即时响应,是数字社交的关键。
  • 海量存储:系统必须可扩展,以容纳用户生成的海量消息文本、图片及音视频数据。

 

3. 概要设计

在概要设计中,我们考虑了系统的核心组件和基本业务的概要设计。

3.1 核心组件

微信群聊系统中,会涉及到如下核心组件和协议。

听说你会架构设计?来,弄一个微信群聊系统图片

  • 客户端:接收手机或 PC 端微信群聊的消息,并实时传输给后台服务器
  • Websocket传输协议:支持客户端和后台服务端的实时交互,开销低,实时性高,常用于微信、QQ 等 IM 系统通信系统
  • 长连接集群:与客户端进行 Websocket 长连接的系统集群,并将消息通过中间件转发到应用服务器
  • 消息处理服务器集群:提供实时消息的处理能力,包括数据存储、查询、与数据库交互等
  • 消息推送服务器集群:这是信息的中转站,负责将消息传递给正确的群组成员
  • 数据库服务器集群:用于存储用户文本数据、图片的缩略图、音视频元数据等
  • 分布式文件存储集群:存储用户图片、音视频等文件数据

 

3.2 业务概要设计

群聊创建

  • 唯一ID分配:当用户请求创建一个新群组时,系统生成一个唯一的群组 ID,通常可以使用分布式 ID 生成器如雪花算法(Snowflake)或直接使用数据库自增 ID。这里我们为了实现简便,采用 MySQL 的自增 ID。
  • 群组信息存储:将群组 ID 和相关信息(例如群名、创建者 ID 等)存储在群组数据库中。
  • 成员关联:将群主添加为群组的创始成员,同时创建者也会成为管理员。
  • 消息历史记录:为了确保新成员能够访问以前的消息,将此新群组的群组 ID 与用户消息关联存储。

除了拉好友建群,微信还实现了面对面建群的能力。

接下来,我们深入探讨了三到四个核心功能的详细设计,包括面对面建群、消息发送与接收及抢红包功能。

 

4. 面对面建群

用户发起面对面建群,并输入一个 4 位数的随机码,周围的用户输入该随机码后可加入群聊,面对面建群功能通常涉及数据表设计和核心业务交互流程如下。

4.1 数据库表设计

  1. User 表:存储用户信息,包括用户 ID、昵称、头像等。
  2. Group 表:存储群组信息,包括群 ID、群名称、创建者 ID、群成员个数等。
  3. GroupMember 表:关联用户和群组,包括用户 ID 和群 ID。
  4. RandomCode 表:存储面对面建群的随机码和关联的群 ID。

 

4.2 核心业务交互流程

听说你会架构设计?来,弄一个微信群聊系统图片

用户 A 在手机端应用中发起面对面建群,并输入一个随机码,校验通过后,等待周围(50 米之内)的用户加入。此时,系统将用户信息以 HashMap 的方式存入缓存中,并设置过期时间为 3min。

{随机码,用户列表[用户A(ID、名称、头像)]}

用户 B 在另一个手机端发起面对面建群,输入指定的随机码,如果该用户周围有这样的随机码,则进入同一个群聊等待页面,并可以看到其它群员的头像和昵称信息。

此时,系统除了根据随机码获取所有用户信息,也会实时更新缓存里的用户信息。

听说你会架构设计?来,弄一个微信群聊系统图片

当第一个用户点击进入该群时,就可以加入群聊,系统将生成的随机码保存在 RandomCode 表中,并关联到新创建的群 ID,更新群成员的个数。

然后,系统将用户信息和新生成的群聊信息存储在 Group、GroupMember 表中

 

成员加入,刷新群员信息

之后 B、C 用户带着随机码加入群聊时,手机客户端向服务器后端发送请求,验证随机码是否有效。服务器后端验证随机码,检查随机码是否存在于缓存中,以及是否在有效期内。

然后,判断当前群成员是否满员(目前普通用户创建的群聊人数最多为 500 人),如果验证通过,服务器后端将用户 B、C 添加到群成员表 GroupMember 中,并返回成功响应。

移动客户端应用收到成功响应后,更新用户 B、C 的群聊列表,展示他们已加入的新群聊。

 

其它技术组件

这样,用户 A 通过创建随机码和周围的用户扫描二维码的方式成功建立了一个面对面建群。这个功能涉及了多个技术组件,包括分布式缓存、数据库、二维码生成和验证等。

同时,在面对面建群的过程中相当重要的能力是标识用户的区域,比如 50 米以内。这个可以用到 redis 的 GeoHash 算法,来获取一个范围内的所有用户信息。

由于篇幅有限,这里不展开赘述,想了解更多和二维码生成及位置算法的细节,可以看我之前的文章:听说你会架构设计?来,弄一个公交&地铁乘车系统。

 

5. 消息发送与接收

当某个成员在微信群里发言,系统需要处理消息的分发、通知其他成员、以及确保消息的显示。以下是这一功能的详细交互步骤,以及数据库存储方案。

 

5.1 交互流程

消息发送和接收时序图如下:

听说你会架构设计?来,弄一个微信群聊系统图片

  1. 用户A在群中发送一条带有图片、视频或音频的消息。
  2. 移动客户端应用将消息内容和媒体文件上传到服务器后端。
  3. 服务器后端接收到消息和媒体文件后,将消息内容存储到 Message 表中,同时将媒体文件存储到分布式文件存储集群中。在 Message 表里,不仅记录了媒体文件的 MediaID,以便关联消息和媒体;还记录了缩略图、视频封面图等等。
  4. 服务器后端会向所有群成员广播这条消息。移动客户端应用接收到消息后,会根据消息类型(文本、图片、视频、音频)加载对应的展示方式。
  5. 当用户点击查看图片、视频或音频缩略图时,客户端应用会根据 MediaID 到对象存储集群中获取对应的媒体文件路径,并将其展示给用户。

这个流程确保了消息和媒体文件的有效存储和展示。用户可以上传和查看各种类型的媒体数据,而服务器后端通过关联 Message 和对象存储服务器中的信息,实现了有效的消息存储和展示。

 

5.2 消息存储和展示

在微信群中保存和展示用户的图片、视频或音频数据,通常需要进行数据存储和展示方面的设计。除了上面面对面建群功能中提到的用户表和群组表以外,还需要以下表结构:

  1. Message表: 用于存储消息,每个消息都有一个唯一的 MessageID,消息类型(文本、图片、视频、音频),消息内容(文字、图片缩略图、视频封面图等),发送者 UserID、接收群 GroupID、发送时间等字段。
  2. Media表: 存储用户上传的图片、视频、音频等媒体数据。每个媒体文件都有一个唯一的 MediaID,文件路径、上传者 UserID、上传时间等字段。
  3. MessageState表: 用于存储用户消息状态,包括 MessageID、用户 ID、是否已读等。在消息推送时,通过这张表计算未读数,统一推送给用户,并在离线用户的手机上展示一个小数字代表消息未读数。

我们知道,MySQL 每次查询 select count 类型的语句时,都会触发全表扫描,所以每次加载消息未读数都很慢。

为了查询性能考虑,我们可以将用户的消息数量存入 Redis,并实时记录一个未读数值。并且,当未读数大于 99 时,就将未读数值置为 100 且不再增加。

当推送用户消息时,只要未读数为 100,就将推送消息数设置为 99+,以此来提升存储的性能和交互的效率。

 

6. 抢红包

抢红包功能允许用户在群聊中发送任意个数和金额的红包,群成员可以抢到随机金额的红包,但要保证每个用户的红包金额不小于 0.01 元。

听说你会架构设计?来,弄一个微信群聊系统图片

抢红包的详细交互流程如下:

  1. 用户接收到抢红包通知,点击通知打开群聊页面
  2. 用户点击抢红包,后台服务验证用户资格,确保用户尚未领取过此红包
  3. 若用户资格验证通过,后台服务分配红包金额并存储领取记录
  4. 用户在微信群中看到领取金额,红包状态更新为“已领取”
  5. 异步调用支付接口,将红包金额更新到钱包里

抢红包功能需要关注抢红包的数据库设计,抢红包实时性和红包分配算法。

 

6.1 数据库设计

红包表 redpack 的字段如下:

  • id: 主键,红包ID
  • totalAmount: 总金额
  • surplusAmount: 剩余金额
  • total: 红包总数
  • surplusTotal: 剩余红包总数
  • userId: 发红包的用户ID

该表用来记录用户发了多少红包,以及需要维护的剩余金额。

 

红包记录表 redpack_record 如下:

  • id: 主键,记录ID
  • redpackId: 红包ID,外键
  • userId: 用户ID
  • amount: 抢到的金额

记录表用来存放用户具体抢到的红包信息,也是红包表的副表。

 

6.2 实时性

1、发红包

  1. 用户设置红包的总金额和个数后,在红包表中增加一条数据,开始发红包
  2. 为了保证实时性和抢红包的效率,在 Redis 中增加一条记录,存储红包 ID 和总人数 n
  3. 抢红包消息推送给所有群成员

 

2、抢红包

从 2015 年起,微信红包的抢红包和拆红包就分离了,用户点击抢红包后需要进行两次操作。这也是为什么明明有时候抢到了红包,点开后却发现该红包已经被领取完了。

抢红包的交互步骤如下:

  1. 抢红包:抢操作在 Redis 缓存层完成,通过原子递减的操作来更新红包个数,到 0 后就说明抢光了。
  2. 拆红包:拆红包时,首先会实时计算金额,一般是通过二倍均值法实现(即 0.01 到剩余平均值的 2 倍之间)。
  3. 红包记录:用户获取红包金额后,通过数据库的事务操作累加已经领取的个数和金额,并更新红包表和记录表。
  4. 转账:为了提升效率,最终的转账为异步操作,这也是为什么在春节期间,红包领取后不能立即在余额中看到的原因。

 

6.3 红包分配算法

红包金额分配时,由于是随机分配,所以有两种实现方案:实时拆分和预先生成。

1、实时拆分

实时拆分,指的是在抢红包时实时计算每个红包的金额,以实现红包的拆分过程。

这个需要我们设计一个好的拆分算法,让红包拆分时一直保证后续待拆分红包的金额不能为空。

实时拆分时,不容易做到拆分的红包金额服从正态分布规律。

 

2、预先生成

预先生成,指的是在红包开抢之前已经完成了红包的金额拆分,抢红包时只是依次取出拆分好的红包金额。

这种方式对拆分算法要求较低,可以拆分出随机性很好的红包金额,但通常需要结合队列使用,而且需要多设计一个表来存储红包的拆分金额。

 

3、二倍均值法

综合上述优缺点考虑,以及微信群聊中的人数不多(目前最高 500 人),所以我们采用实时拆分的方式,用二倍均值法来生成随机红包,只满足随机即可,不需要正态分布。

故可能出现很大的红包差额,但这更刺激不是吗



Tags:架构   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
对于微服务架构监控应该遵守的原则
随着软件交付方式的变革,微服务架构的兴起使得软件开发变得更加快速和灵活。在这种情况下,监控系统成为了微服务控制系统的核心组成部分。随着软件的复杂性不断增加,了解系统的...【详细内容】
2024-04-03  Search: 架构  点击:(5)  评论:(0)  加入收藏
大模型应用的 10 种架构模式
作者 | 曹洪伟在塑造新领域的过程中,我们往往依赖于一些经过实践验证的策略、方法和模式。这种观念对于软件工程领域的专业人士来说,已经司空见惯,设计模式已成为程序员们的重...【详细内容】
2024-03-27  Search: 架构  点击:(13)  评论:(0)  加入收藏
哈啰云原生架构落地实践
一、弹性伸缩技术实践1.全网容器化后一线研发的使用问题全网容器化后一线研发会面临一系列使用问题,包括时机、容量、效率和成本问题,弹性伸缩是云原生容器化后的必然技术选择...【详细内容】
2024-03-27  Search: 架构  点击:(10)  评论:(0)  加入收藏
京东小程序数据中心架构设计与最佳实践
一、京东小程序是什么京东小程序平台能够提供开放、安全的产品,成为品牌开发者链接京东内部核心产品的桥梁,致力于服务每一个信任我们的外部开发者,为不同开发能力的品牌商家提...【详细内容】
2024-03-27  Search: 架构  点击:(9)  评论:(0)  加入收藏
从 MySQL 到 ByteHouse,抖音精准推荐存储架构重构解读
ByteHouse是一款OLAP引擎,具备查询效率高的特点,在硬件需求上相对较低,且具有良好的水平扩展性,如果数据量进一步增长,可以通过增加服务器数量来提升处理能力。本文将从兴趣圈层...【详细内容】
2024-03-22  Search: 架构  点击:(23)  评论:(0)  加入收藏
全程回顾黄仁勋GTC演讲:Blackwell架构B200芯片登场
北京时间3月19日4时-6时,英伟达创始人黄仁勋在美国加州圣何塞SAP中心登台,发表GTC 2024的主题演讲《见证AI的变革时刻》。鉴于过去一年多时间里AI带来的生产力变革,以及英伟达...【详细内容】
2024-03-19  Search: 架构  点击:(17)  评论:(0)  加入收藏
高并发架构设计(三大利器:缓存、限流和降级)
软件系统有三个追求:高性能、高并发、高可用,俗称三高。本篇讨论高并发,从高并发是什么到高并发应对的策略、缓存、限流、降级等。引言1.高并发背景互联网行业迅速发展,用户量剧...【详细内容】
2024-03-13  Search: 架构  点击:(6)  评论:(0)  加入收藏
有了LLM,所有程序员都将转变为架构师?
编译 | 言征 出品 | 51CTO技术栈(微信号:blog51cto)生成式人工智能是否会取代人类程序员?可能不会。但使用生成式人工智能的人类可能会,可惜的是,现在还不是时候。目前,我们正在见...【详细内容】
2024-03-07  Search: 架构  点击:(19)  评论:(0)  加入收藏
如何判断架构设计的优劣?
架构设计的基本准则是非常重要的,它们指导着我们如何构建可靠、可维护、可测试的系统。下面是这些准则的转换表达方式:简单即美(KISS):KISS原则的核心思想是保持简单。在设计系统...【详细内容】
2024-02-20  Search: 架构  点击:(36)  评论:(0)  加入收藏
通用数据湖仓一体架构正当时
这篇博文中提出的建议并不新鲜。事实上许多组织已经投入了数年时间和昂贵的数据工程团队的工作,以慢慢构建这种架构的某个版本。我知道这一点,因为我以前在Uber和LinkedIn做过...【详细内容】
2024-01-15  Search: 架构  点击:(76)  评论:(0)  加入收藏
▌简易百科推荐
对于微服务架构监控应该遵守的原则
随着软件交付方式的变革,微服务架构的兴起使得软件开发变得更加快速和灵活。在这种情况下,监控系统成为了微服务控制系统的核心组成部分。随着软件的复杂性不断增加,了解系统的...【详细内容】
2024-04-03  步步运维步步坑    Tags:架构   点击:(5)  评论:(0)  加入收藏
大模型应用的 10 种架构模式
作者 | 曹洪伟在塑造新领域的过程中,我们往往依赖于一些经过实践验证的策略、方法和模式。这种观念对于软件工程领域的专业人士来说,已经司空见惯,设计模式已成为程序员们的重...【详细内容】
2024-03-27    InfoQ  Tags:架构模式   点击:(13)  评论:(0)  加入收藏
哈啰云原生架构落地实践
一、弹性伸缩技术实践1.全网容器化后一线研发的使用问题全网容器化后一线研发会面临一系列使用问题,包括时机、容量、效率和成本问题,弹性伸缩是云原生容器化后的必然技术选择...【详细内容】
2024-03-27  哈啰技术  微信公众号  Tags:架构   点击:(10)  评论:(0)  加入收藏
DDD 与 CQRS 才是黄金组合
在日常工作中,你是否也遇到过下面几种情况: 使用一个已有接口进行业务开发,上线后出现严重的性能问题,被老板当众质疑:“你为什么不使用缓存接口,这个接口全部走数据库,这怎么能扛...【详细内容】
2024-03-27  dbaplus社群    Tags:DDD   点击:(11)  评论:(0)  加入收藏
高并发架构设计(三大利器:缓存、限流和降级)
软件系统有三个追求:高性能、高并发、高可用,俗称三高。本篇讨论高并发,从高并发是什么到高并发应对的策略、缓存、限流、降级等。引言1.高并发背景互联网行业迅速发展,用户量剧...【详细内容】
2024-03-13    阿里云开发者  Tags:高并发   点击:(6)  评论:(0)  加入收藏
如何判断架构设计的优劣?
架构设计的基本准则是非常重要的,它们指导着我们如何构建可靠、可维护、可测试的系统。下面是这些准则的转换表达方式:简单即美(KISS):KISS原则的核心思想是保持简单。在设计系统...【详细内容】
2024-02-20  二进制跳动  微信公众号  Tags:架构设计   点击:(36)  评论:(0)  加入收藏
详解基于SpringBoot的WebSocket应用开发
在现代Web应用中,实时交互和数据推送的需求日益增长。WebSocket协议作为一种全双工通信协议,允许服务端与客户端之间建立持久性的连接,实现实时、双向的数据传输,极大地提升了用...【详细内容】
2024-01-30  ijunfu  今日头条  Tags:SpringBoot   点击:(9)  评论:(0)  加入收藏
PHP+Go 开发仿简书,实战高并发高可用微服务架构
来百度APP畅享高清图片//下栽のke:chaoxingit.com/2105/PHP和Go语言结合,可以开发出高效且稳定的仿简书应用。在实现高并发和高可用微服务架构时,我们可以采用一些关键技术。首...【详细内容】
2024-01-14  547蓝色星球    Tags:架构   点击:(115)  评论:(0)  加入收藏
GraalVM与Spring Boot 3.0:加速应用性能的完美融合
在2023年,SpringBoot3.0的发布标志着Spring框架对GraalVM的全面支持,这一支持是对Spring技术栈的重要补充。GraalVM是一个高性能的多语言虚拟机,它提供了Ahead-of-Time(AOT)编...【详细内容】
2024-01-11    王建立  Tags:Spring Boot   点击:(124)  评论:(0)  加入收藏
Spring Boot虚拟线程的性能还不如Webflux?
早上看到一篇关于Spring Boot虚拟线程和Webflux性能对比的文章,觉得还不错。内容较长,抓重点给大家介绍一下这篇文章的核心内容,方便大家快速阅读。测试场景作者采用了一个尽可...【详细内容】
2024-01-10  互联网架构小马哥    Tags:Spring Boot   点击:(115)  评论:(0)  加入收藏
站内最新
站内热门
站内头条