前言
在互联网时代,消息服务已成为必备的产品。比如微信、钉钉和QQ
等以IM
为核心功能的产品。还有一部分是直播间内用户聊天互动,形式上也是常见的IM
消息流;直播间内常见的消息流包括直播弹幕、互动聊天、信令、涂鸦、消息推送等。在线教育行业内消息服务尤其重要,直播授课过程中的互动答题、涂鸦、表演、点赞等,不过对消息可靠性有非常高的要求,而且对消息的即时性也非常敏感。
消息服务
当说到消息服务的时候大家都会想到微信等常见的IM
产品,所以直播间内的聊天消息经常类比于群聊,而1v1
的消息类比于单聊。
大部分人听到消息服务的时候都觉得消息服务很简单,不就是分为单聊和群聊两种。单聊不就是把消息转发给某个用户;群聊不就是把消息广播给聊天室内所有的用户。
那消息服务面临的挑战有哪些呢,看下图:
业务场景分析
针对上面的难点,我们来梳理一下如何构建直播的消息系统。
面临的问题
初期业务主要的场景是直播间的群聊消息以及一小部分的单聊消息。由于是教育场景,所以业务在划分聊天室的时候是以班级为单位进行划分的,假设每个聊天室的人数为500人。
问题一:用户的维护
直播场景的群聊与微信等常见的群聊在用户维护上有很大区别。微信的群用户关系相对比较固定,用户进群退群是相对低频操作,用户集合相对固定。而直播间里的用户进出是非常频繁的,而且直播间是有时效性的。实际进出直播间峰值QPS
不会超过1万,使用Redis
可以解决聊天室用户列表存储及过期清理问题。
问题二:消息转发
当一个500人的聊天室所有用户同时发送消息时,消息的转发QPS
为500*500=2.5w。从直播用户端视角考虑:
实时性:如果消息服务做消峰处理,峰值消息的堆积会造成消息延时增大,而有些信令消息具有时效性,太大延迟会影响用户的体验及互动实时性。
用户体验:端展示各类用户聊天和信令消息一般一屏不会超过10-20条; 如果每秒超过20条消息下发会出现持续刷屏的现象; 大量的消息也会给端上带来持续的高负荷。
因此我们为消息定义了不同的优先级。高优先级消息优先转发处理并且保证不丢弃; 低优先级消息进行一定丢弃策略后再进行转发。
问题三:历史消息
业务上需要生成回放视频,需要获取历史信令、互动聊天等消息。要求能够快速写入历史消息以保证消息转发的时效性。
消息的保存主要包含写扩散和读扩散两大类。我们采用读扩散的方式,读扩散可以减少存储空间,也可以减少消息保存的时间。考虑到回放的优先级不高,所以在存储组件的选择上我们选择了Pika
。Pika
是接口与Redis
类似可以减少学习、开发成本。同时由于它是采用追加的方式,所以写性能可以与Redis
媲美。
问题四:消息顺序
信令消息顺序的要求,需要保证同一个人发送消息的顺序,以及需要保证同一个聊天室内的用户收到消息顺序都是相同的。
解决消息顺序可以使用Kafka
之类的队列来保证,但是用Kafka
有一定的延迟。为了降低延迟我们采用一致性哈希的策略来处理消息的转发,稍后会详细介绍。
设计目标
打造稳定、高效的消息通讯服务