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

  • 当用户点击查看图片、视频或音频缩略图时,客户端应用会根据 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 年起,微信红包的抢红包和拆红包就分离了 , 用户点击抢红包后需要进行两次操作 。这也是为什么明明有时候抢到了红包,点开后却发现该红包已经被领取完了 。


    推荐阅读