找回密码
 会员注册
查看: 15|回复: 0

玩转直播系列之消息模块演进(3)

[复制链接]

2万

主题

0

回帖

7万

积分

超级版主

积分
72653
发表于 2024-10-5 11:08:46 | 显示全部楼层 |阅读模式
一、背景即时消息(IM)系统是直播系统重要的组成部分,一个稳定的,有容错的,灵活的,支持高并发的消息模块是影响直播系统用户体验的重要因素。IM长连接服务在直播系统有发挥着举足轻重的作用。本篇文章针对秀场直播,简单地描述一下消息模型,说明一下我们消息模型的架构,并结合我们一年以来,通过处理不同的业务线上问题,来进行演进式的消息模型架构的升级与调整,将此整理成文,并分享給大家。在目前大部分主流的直播业务中,推拉流是实现直播业务最基本的技术点,消息技术则是实现观看直播的所有用户和主播实现互动的关键技术点,通过直播IM系统模块,我们可以完成公屏互动,彩色弹幕,全网送礼广播,私信,PK等核心秀场直播的功能开发。"IM消息"作为用户和用户,用户和主播之间"沟通"的信息桥梁,如何保证"信息桥梁"的在高并发场景下保持稳定可靠,是直播系统演进过程中一个重要的话题。二、直播消息业务在直播业务中,有几个核心的关于消息模型的概念,我们先简单地介绍一下,方便大家对直播相关的消息模型有一个整体上的理解。2.1 主播与用户主播和观众,对于IM系统来说,都是一个普通用户,都会有一个唯一用户标识,也是IM分发到点对点消息的重要标识。2.2 房间号一个主播对应一个房间号(RoomId),主播在开播之前,进行身份信息验证之后,就会绑定唯一的房间号,房间号是IM系统进行直播间消息分发的重要标识。2.3 消息类型划分按照直播业务特性,IM消息划分的方式有很多方式,例如按照接收方维度进行划分,按照直播间消息业务类型进行划分,按照消息的优先级,存储方式都可以进行不同的划分等等方式。通常,我们按照接收方维度进行划分有如下几个类型的消息:点对点消息(单播消息)直播间消息(群播消息)广播消息按照具体的业务场景有如下几个类型的消息:礼物消息公屏消息PK消息业务通知类消息消息能够实时准确地分发到对应的群体或者单个用户终端都是非常必要的。当然好一点的IM消息模型也能够赋能业务一些新的能力,例如如下的能力:统计每个直播间的实时在线人数捕获用户进出直播间的事件统计每个用户实时进入直播间的时间2.4 消息优先级直播的消息是有优先级的,这一点是很重要的,与微信,QQ等聊天IM产品不一样的地方是直播间消息是分优先级的。微信等聊天消息产品,不管是私聊还是群聊,每个人发送消息的优先级基本上是一样的,不存在谁的消息优先级高,谁的消息优先级低,都需要将消息准确实时地分发到各个业务终端,但是直播因为业务场景的不同,消息分发的优先级也是不一样的。举例来说,如果一个直播间每秒只能渲染15~20个消息,如果一个热点直播间一秒钟产生的消息量大于20条或者更多,如果不做消息优先级的控制,直接实时分发消息,那么导致的结果就是直播间公屏客户端渲染卡顿,礼物弹框渲染过快,用户观看体验大幅下降,所以我们要针对不同业务类型的消息,给出不同的消息优先级。举例来说,礼物消息大于公屏消息,同等业务类型的消息,大额礼物的消息优先级又大于小额礼物的消息,高等级用户的公屏消息优先级高于低等级用户或者匿名用户的公屏消息,在做业务消息分发的时候,需要根据实际的消息优先级,选择性地进行消息准确地分发。三、消息技术点3.1 消息架构模型3.2 短轮询 VS 长链接3.2.1 短轮询3.2.1.1 短轮询的业务模型首先我们先简单地描述一下短轮询时间的过程和基本设计思想:客户端每隔2s轮询服务器接口,参数是roomId和timestamp,timestamp第一次传递0或者null。服务器根据roomId和timestamp查询该房间在timestamp时间戳后产生的消息事件,返回限定条数的消息例如(例如返回10~15条,当然在这个timestamp之后产生的消息数远远大于15条,不过因为客户端渲染能力有限和过多的消息展示,会影响用户体验,所以限制返回的条数),并且同时返回这些消息中最后一条消息产生的时间戳timestamp,作为客户端下次请求服务器的基准请求时间戳。以此反复,这样就可以每隔2s按照各个终端要求,更新每个直播间的最新消息了整体的主体思想如上图所示,不过具体的时间可以再做精细化处理,后续再做具体的说明和细节说明。3.2.1.2 短轮询的存储模型短轮询的消息存储与正常的长连接的消息存储有一定的区别,不存在消息扩散的问题,我们需要做的消息存储需要达到如下的业务目标:消息插入时间复杂度要相对比较低;消息查询的复杂度要相对比较低;消息的存储的结构体要相对比较小,不能占用太大的内存空间或者磁盘空间;历史消息能够按照业务需要做磁盘持久化存储;结合上述4点的技术要求,毕竟经过小组成员的讨论,我们决定使用Redis的SortedSet数据结构进行存储,具体实现思路:按照直播间产品业务类型,将业务消息划分为如下四大类型:礼物,公屏,PK,通知。一个直播间的消息使用四个Redis的SortedSet数据结构进行存储,SortedSet的key分别是"live::roomId::gift","live::roomId::chat","live::roomId::notify","live::roomId::pk",score分别是消息真实产生的时间戳,value就是序列化好的json字符串,如下图所示:客户端轮询的时候,服务端查询的逻辑如下所示:很多同学会疑问,为什么不适用Redis的list的数据结构呢?如下图会进行详细的说明:最后我们再对比一下Redis的SortedSet和Redis的List这两个数据结构在直播消息存储的时候,时间复杂度的相关分析。以上,就是我们使用Redis的SortedSet数据结构进行消息存储的一些简单的设计思考,后续我们也会提到端轮询的编码时候,需要的注意点。3.2.1.3短轮询的时间控制短轮询的时间控制及其重要,我们需要在直播观众观看体验QoE和服务器压力之间找到一个很好的平衡点。轮询的间隔时间太长,用户体验就会下降很多,直播观看体验就会变差,会有"一顿一顿"的感觉。短轮询的频率过高,会导致服务器的压力过大,也会出现很多次"空轮询",所谓的"空轮询"就是无效轮询,也就是在上一秒有效轮询返回有效消息之后,间隔期直播间没有产生新的消息,就会出现无效的轮询。vivo直播目前每日的轮询次数是10+亿次,晚观看直播高峰期的时候,服务器和Redis的CPU负载都会上升,dubbo的服务提供方的线程池一直处于高水位线上,这块需要根据机器的和Redis的实时负载的压力,做服务器的水平扩容和Redis Cluster的节点扩容,甚至让一些超高热度值的直播间负载到指定的Redis Cluster集群上,做到物理隔离,享受到"VIP"服务,确保各个直播间的消息相互不影响。直播人数不一样的直播间,轮询的时间也是可以配置的,例如人数比较少的直播,百人以下的直播间,可以设置比较高频的轮询频率,例如1.5s左右,超过300人以上的,1000人以下可以2s左右,万人直播间可以设置2.5s左右,这些配置应该都可以通过配置中心实时下发,客户端能够实时更新轮询的时间,调整的频率可以根据实际直播间用户体验的效果,并且结合服务器的负载,找到一个轮询间隔的相对最佳值。在线人数轮询间隔1001.7>3001.8>10002
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-11 21:09 , Processed in 1.016161 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表