3.2 业务概要说明在业务概要说明里,我们关注用户的交互方式和数据存储......
面试官:稍等一下 , 群聊系统的好友建群功能比较简单,拉好友列表存数据就可以了!你用过面对面建群吧,可以简要说一下如何设计面对面建群功能吗?
我:(内心 OS,还好之前在吃饭时用过面对面建群结账 , 不然就G了),好的,群聊系统除了拉好友建群外,还支持面对面建群的能力 。
4. 面对面建群用户发起面对面建群后,系统支持输入一个 4 位数的随机码,周围的用户输入同一个随机码便可加入同一个群聊 , 面对面建群功能通常涉及数据表设计和核心业务交互流程如下 。
4.1 数据库表设计
- User 表:存储用户信息 , 包括用户 ID、昵称、头像等 。
- Group 表:存储群组信息 , 包括群 ID、群名称、创建者 ID、群成员个数等 。
- GroupMember 表:关联用户和群组 , 包括用户 ID 和群 ID 。
- RandomCode 表:存储面对面建群的随机码和关联的群 ID 。
4.2 核心业务交互流程

文章插图
图片
用户 A 在手机端应用中发起面对面建群,并输入一个随机码 , 校验通过后 , 等待周围(50 米之内)的用户加入 。此时,系统将用户信息以 HashMap 的方式存入缓存中,并设置过期时间为 3min 。
{随机码,用户列表[用户A(ID、名称、头像)]}用户 B 在另一个手机端发起面对面建群,输入指定的随机码,如果该用户周围有这样的随机码,则进入同一个群聊等待页面,并可以看到其它群员的头像和昵称信息 。此时,系统除了根据随机码获取所有用户信息,也会实时更新缓存里的用户信息 。

文章插图
成员A进群当第一个用户点击进入该群时,就可以加入群聊 , 系统将生成的随机码保存在 RandomCode 表中,并关联到新创建的群 ID,更新群成员的个数 。
然后,系统将用户信息和新生成的群聊信息存储在 Group、GroupMember 表中,并实时更新群成员个数 。
成员B加入然后,B 用户带着随机码加入群聊时,手机客户端向服务器后端发送请求,验证随机码是否有效 。后台服务检查随机码是否存在于缓存中,如果存在 , 则校验通过 。
然后,根据 Group 中的成员个数,来判断当前群成员是否满员(目前普通用户创建的群聊人数最多为 500 人) 。
如果验证通过,后台将用户 B 添加到群成员表 GroupMember 中,并返回成功响应 。
面试官:如果有多个用户同时加入,MySQL 数据库如何保证群成员不会超过最大值呢?
我:有两种方式可以解决 。一个是通过 MySQL 的事务,将获取 Group 群成员数和插入 GroupMember 表操作放在同一个事务里,但是这样可能带来锁表的问题,性能较差 。
另一种方式是采用 redis 的原子性命令incr 来记录群聊的个数,其中 key 为群聊ID,value 为当前群成员个数 。
当新增群员时,首先将该群聊的人数通过 incr 命令加一 , 然后获取群成员个数 。如果群员个数大于最大值,则减一后返回群成员已满的提示 。
使用 Redis 的好处是可以快速响应,并且可以利用 Redis 的原子特性避免并发问题,在电商系统中也常常使用类似的策略来防止超卖问题 。
位置算法同时,在面对面建群的过程中相当重要的能力是标识用户的区域,比如 50 米以内 。这个可以用到 Redis 的 GeoHash 算法,来获取一个范围内的所有用户信息 。
由于篇幅有限 , 这里不展开赘述,想了解更多位置算法相关的细节,可以看我之前的文章:听说你会架构设计?来 , 弄一个公交&地铁乘车系统 。
面试官:嗯不错,那你再讲一下群聊系统里的消息发送和接收吧!
5. 消息发送与接收我:当某个成员在微信群里发言,系统需要处理消息的分发、通知其他成员、以及确保消息的显示 。
推荐阅读
- 一文读懂Android架构演进历程
- Instagram 早期技术架构,你了解了吗?
- 五百万和杨颖你会选择哪个?
- 减肥多吃这3种食物,少吃这3种食物,你会很快瘦下来
- 空气炸锅致癌是真的吗 听说空气炸锅致癌是真的吗
- 醋泡黑豆的作用,听说陈醋泡黑豆不错黑豆有大圆粒的还有小长形的是用哪种黑豆
- 普洱大叶种与小叶种,你会区分吗?
- 听说你会架构设计?来,弄一个微信群聊系统
- 时尚中短发、展现绝美女人气质,你会爱上哪款呢
- 当听说汪峰拥有30亿资产,葛荟婕的回应亮了,真是人间清醒
