2020年因为受到疫情的影响,各种电商直播纷纷涌入大家的视野,很多商家都通过直播的方式来售卖自己的产品。直播弹幕是直播系统的核心功能之一。如何迅速作出一个有很好扩展性的弹幕系统?如何应对业务迅速发展?相信很多工程师/架构师都有自己的想法。哔哩哔哩作为国内首屈一指的弹幕视频网站,今天我们就一起来看看他们是如何做的。
一对多直播系统开发,重点是这些
高并发实时弹幕是一种互动的体验。对于互动来说,考虑最多的地方就是:高稳定性、高可用性以及低延迟这三个方面。
高稳定性,为了保证互动的实时性,所以要求连接状态稳定。
高可用性,相当于提供一种备用方案,比如,互动时如果一台机器挂了,此时必须保证可以和另外一台机器连接,这样就从侧面解决了用户连接不中断的问题。
对于低延迟,弹幕的延迟周期控制在 1 秒以内,响应是比较快的,所以可以满足互动的需求。

一对多直播系统开发,百万用户在线,直播弹幕系统是如何实现的?_第1张图片

一对多直播系统开发,GOIM 系统的优化之路
一、内存优化
内存优化主要分为以下三个方面:
1.一个消息一定只有一块内存
使用 Job 聚合消息,Comet 指针引用。
2.一个用户的内存尽量放到栈上
内存创建在对应的用户 Goroutine(Go 程)中。
3.内存由自己控制
主要是针对 Comet 模块所做的优化,可以查看模块中各个分配内存的地方,使用内存池。
二、模块优化
1.消息分发一定是并行的并且互不干扰
要保证到每一个 Comet 的通讯通道必须是相互独立的,保证消息分发必须是完全并列的,并且彼此之间互不干扰。
2.并发数一定是可以进行控制的
每个需要异步处理开启的 Goroutine(Go 协程)都必须预先创建好固定的个数,如果不提前进行控制,那么 Goroutine 就随时存在爆发的可能。
3.全局锁一定是被打散的
Socket 链接池管理、用户在线数据管理都是多把锁;打散的个数通常取决于 CPU,往往需要考虑 CPU 切换时造成的负担,并非是越多越好。
模块优化的三个方面,主要考虑的问题就是,分布式系统中会出现的单点问题,即当一个用户在建立链接后,如果出现故障,其余用户建立的链接不能被影响。
测试是实践过程中最不可缺少的一部分,同时,测试的数据也是用来进行参考比照的最好工具。

四、使用长连接替换短连接轮询方案

长连接整体架构图

一对多直播系统开发,百万用户在线,直播弹幕系统是如何实现的?_第2张图片

长连接业务模块用于用户进入直播间的验证工作;
服务端之间的通讯使用基础研发团队研发的 tardis 框架来进行服务的调用,该框架基于 gRPC,使用 etcd 做服务发现。
我们采用了订阅推送模型,举例说明,用户 1 订阅了 A 直播,A 直播有新的消息:
推送层查询订阅关系后,知道有用户 1 订阅了 A 直播,同时知道用户 1 在连接层 1 这个节点上,那么就会告知连接层有新的消息;
连接层 1 收到告知消息后,会等待一小段时间(毫秒级),再拉取一次用户 1 的消息,然后推送给用户 1。
如果是大直播间(订阅用户多),那么推送层与连接层的告知/拉取模型,就会自动降级为广播模型。
五、直播弹幕优化的最终瓶颈只有流量
1.调节用户最优接入节点
使用 Svrlist 模块支持,选取距离用户最近的最稳定的节点,调控 IP 段,然后进行接入。
2.IDC 的服务质量监控:掉线率
判断一个节点是否稳定,需要不断收集大量的用户链接信息,此时就可以使用监控来查询掉线率,然后不断调优,收集最终的结果去做一个拓扑图(全国范围),在拓扑图当中就可以判断出城市到机房之间的最优线路。
3.流量控制
对于弹幕来说,当用户量到达一定级别时,需要考虑的问题还是流量控制,这也是对于花销成本的控制,当买的机房的带宽,是以千兆带宽为计费标准时,当有超标时,一定要将超标部分的流量切走,以此实现了流量控制的功能。