直播评论系统是电商系统一个经常使用的功能,即在发布新品的时候,为了吸引用户参与和营造互动气氛,让参与的每一个人均可以发消息,发完后每一个人均可以即时看到新消息,原型和 http://live.oneplusbbs.com/ 差很少。前端
假如要求在线用户数是20W,你会如何设计系统呢?sql
任何系统设计都不能离开用例设计,脱离业务讲技术都是耍流氓,咱们先分析功能需求:后端
一、发表消息spa
假设消息最长内容为1K,能够有图片。 设计
二、接收消息3d
要求用户不低于2秒能收到最新消息。 blog
这里最基本的功能,而后咱们分析下一些非功能性需求: 接口
一、发表消息 图片
A、要可以限制一些广告或政治敏感内容,这块看公司的基础服务是否完善,若是有相应的功能,能够接入相关服务,不过要注意此服务也要扩容;没有的建议接入第三方相关服务;资源
B、要防刷屏,即防止某个用户单位时间发送太多的评论,因此要作下频率限制;
C、图片的保存,咱们能够算一下带宽,若是一张图片大小是5K,同时在线20W人,则一条消息须要约1G的带宽,建议将图片放入CDN;
另外还要注意回源的问题,即一张图片第一次访问的时候会有大量的回源,最好是作预取的处理,即在发表评论的时候就主动推送到CDN上。
二、接收消息
20W人在线,假如1秒钟会发送1000条消息,每条消息平均长度是500字节,则须要100G的带宽,这估计也不是我等私有云机房所能承受的。
因此这块建议采用购买第三方服务来实现,若是实在是要本身实现,至少这块得放入公有云上,而且作好带宽的预估及限流手段,防止机房带宽被打爆。
三、存储的设计
首先要考虑的是要不要存本地,若是不用备份,能够直接发送给第三方就不用本地保存。
若是须要本地保存, 20W在线用户,若是有5%的人同时发消息,则有1W的TPS,因此写Mysql是不大现实的。能够考虑写入到Redis中,Redis List类型结构适合此类场景。
消息重复接收问题
消息推送系统很难保证消息不会重复,因此前端接收新消息时须要和已经接到的消息ID进行对比,如存在则过滤掉;推送给第三方时每条消息都要加上消息ID,消息ID可用UUID生成,简单实用。
*乱序和延迟问题*
对于乱序的状况,保证消息展现时按时间倒序排列的。
若是新收到一条消息,多是5分钟前发送的,前端展现时须要判断是否小于当前屏幕的最先消息的发送时间,若是是就能够忽略这条消息了。
系统的可用性设计
1、若是第三方消息推送服务挂了,怎么办?
能够有几个方案:
一、多选一家消息推送服务商;
二、兜底方案,若是全部第三方服务都挂了,可让前端使用轮询方案,但轮询的间隔须要后端接口给出,能够在后台配置,根据压力大小作调整。
2、如何保证消息不丢
要注意Redis的持久化设置,AOF模式下有1秒刷盘的策略,极端状况下,可能会丢失1秒的消息;固然了若是要作到彻底不丢失消息则能够配置每次都刷盘,这须要结合业务状况去平衡。
总结
还有不少细节这里没有展现,如监控,怎样知道用户收到消息的延迟不超过2秒;降级,哪些是非核心功能,但可能会消耗不少资源的,像发送图片,若是回源压力比较大的状况也是能够关闭的。