IM系统中群聊未读消息的设计思路

前言

最近在自己写一个IM即时通讯的一个系统,类似为一个社区的样子,昨天进行了对数据库设计的的重构,在重构的过程中,遇到了未读消息设计的这个问题,之前一点功课都没做的时候,作者的想法就非常的天真,每次有一个消息发过来就在缓存中增加未读数,当时没有想到一个用户有多个群聊,而且每个群聊还会出现重复记录的问题,所以就这次重构之前,作者是阅读过一些大佬的文章,还有几经询问之下有了这次的设计探索

声明:本篇文章是作者自己的构思历程,有好的想法欢迎提出,遇到错误也欢迎对作者提出斧正意见,最后转载请声明出处

第一次设计尝试:为每个主频道增加一个用户的最后离开时间

  1. 系统主体设计
    首先作者设计的这个系统是对类似于Discord这种社交应用的一种想法上的复现,主体是每个用户都可以加入和创建一个主频道,主频道下有只有一级是子频道,没有子子频道

  2. 初次尝试
    首先对于将未读消息数计入缓存这个如果频道数多了之后就很不现实,所以采取一种比较通用的方法就是,通过头和尾的时间戳来锁定未读消息的时间戳

    作者初次是为主体频道增加了一个用户最后的离开时间,想的是每次用户登录进来这个频道后,用登录的时间戳减去上次离开的时间戳,上了个厕所回来之后发现这种想法很不现实,只是对大频道进行一次离开时间戳记录,各个子频道,作者又如何知道用户是什么时候进去,什么时候离开,显然这个想法有点不太管用了

第二次设计尝试:新建表记录子频道的最后离开时间

作者确实也百度了很多也问了AI,相较于上一次的异想天开,这次给出的方法正常许多,新建立一个表

如上图所示,不管是以用户为主体还是以频道为主体来记录这个最后的活跃时间戳,数据量都是非常大的,就比如有十个用户和十个频道,当这十个用户全部加入这十个频道后,就需要为这个表去添加 100 行数据来维护,可想而知这个增量还是挺大的,一个主频道可能不止区区十个子频道

到这里,经过我的百度和各种思考,我发现单从数据库的层面想来让这个问题得到很好的解决的话有点不太现实,所以我发动了最后一个方法,去各个群里询问大佬们的想法

最终的设计:抛弃数据库的设计

当我抛出问题后有一个大佬很快给出一个思路为什么不可以记录在客户端呢,我顿时茅塞顿开,相比于记录于服务端,数据库承受的压力是相当大的,简简单单的时间戳如果去记录在客户端不仅对每个用户的压力很小,而且每个用户加入的频道数也可能不太多,大多数都在 50 个以下,这样不仅速度能够得到提升,而且还省去了服务端的业务压力,只用关心对消息的存放就好

所以最终在前端对消息未读业务设计为 json 存储于 localStorage 中进行持久化处理

总结

这次的设计思路的历程让人给我最大的感触就是,有一些对于用户个人的业务,不方便进行大规模的存储和计算的时候,是否可以将压力分摊到个人的身上,同时同时设计前后端的时候,多想想前端能干一些什么,压力不要全部给到后端,前后端分离嘛,不仅仅是要做到高内聚低耦合,还要想着如何优雅的去实践这一理论,那么今天的分析就到这,感谢您能看到这里,下次我们再聊,Bye~

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MY7eMe5x' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片