声网揭秘:打造百万级用户毫秒级实时音视频系统的秘密

发表时间: 2022-04-07 19:00

大规模实时音视频(RTC)是疫情时代火热的在线课堂、直播、电话会议等的技术基础,但对于多数工程师来说,自研 RTC 系统的架构设计在客户端、服务端、运维、测试和质量监控上仍存在很多难点。因此我们整理了 QCon 全球软件开发大会(2021)北京站上,声网 Agora 行业架构师董海冰分享的三部分内容:RTC(实时音视频)的基础概念、场景及特点分析;自研 RTC 的架构设计和难点;展望 RTC 未来,帮你扣开实时音视频系统架构设计的大门。以下为老师分享的正文。(下文以董海冰老师第一人称叙述)


RTC(实时音视频)的基础概念、场景及特点分析

WebRTC 更侧重于浏览器端,拥有诸多成熟的音视频解决方案,搭建成本低,便于初学者上手,今年起已成为 W3C 正式标准。


我们提及 RTC 多指 Native RTC。Native RTC 可用私有协议,需要 Native 客户端支持,拥有更大的弹性和扩展空间。


实时音视频 QE 的铁三角为音画质量、实时和流畅。音画质量关注分辨率、帧率等,流畅关注卡顿、抖动、丢帧等,实时则关注首帧、音画同步、延时等。这三者是动态平衡的,如高画质必然影响实时和流畅。除此之外,可伸缩性和可用性也不容忽视。


实时音视频的目标为动态条件下实时传输,需在客观情况下寻求以上因素的最优解。其延时必须小于 1s,以 200 ms 或 300 ms 为佳。另外,需要及时交互的远程控制和云游戏场景可能要求更高,在 100ms 左右,甚至低至几十 ms。在如此短的延时下,要实现不同网络中良好的音画质量,挑战不容小觑。


互联网行业中大量成熟解决方案主要依赖三板斧:缓存、异步、分布式。对于实时音视频来说,他山之石,是否可以攻玉呢?


首先传统的缓存,时间为秒级或分钟级,难以达到毫秒级,因此在 RTC 上只能小范围应用。其次,即使实现了并行处理,但在迅速反馈最终结果上仍存在巨大挑战。而对于分布式方案来说,传统互联网的 HTTP 协议很可能无状态,即无法及时感知通讯期间的状态变化和异常,因此难以满足 RTC 的要求。因此以上三板斧在 RTC 上难当大任。

RTC 教育功能模块图

实时音视频在教育领域中应用广泛,场景众多,功能复杂,如下图为某实时音视频在教育领域中应用的实例。


如图所示,老师端需实现实时音视频、消息、互动白板三种服务,学生端有连麦(即可实时互动)和近场(即可能选择性订阅的游客)远场(即用 CDN 转播推流的超级大班课)三种情况;回看功能需将音视频文件持久化在云存储或 OSS 中;监管问题方面需 AI 智能审核、掐断不合法的音视频流。


实现以上功能有许多问题,如成本、效率、人力等资源问题,客户端、服务端等选型问题,跨平台、跨国、跨区域或运营商的网络问题,弱网、Lastmile、3A 处理、终端适配等技术难点问题,以及质量监控和测试方面的问题。


RTC 教育场景技术架构图

我们自研 TutorMeet+部署图如下所示:



Configurator 是本系统的统一配置。学生端会先访问静态文件,通过 Configurator 取到合适的信令网关。随后 Room Server 负责管理房间或频道的逻辑,如频道中的人员、角色和彼此是否存在实时互动关系等。接着,Room Server 再通过 Allocator 搜索更近的 Media Server 网关。此处标准 WebRTC Gateway 和非标 RTC 的 Gateway 均可。最后,再接上 SFU、MCU 和一些图中未表示的辅助系统(如精彩剪辑、推流服务等)即可。


此外,本系统通过 Consul 在不同的区域或机房部署基数节点,实现了统一的全球配置和动态增减,通过 Monitor 监控和预设算法自动 Kill 业务异常服务,保证新用户不会访问到有问题的服务。


自研 RTC 系统的架构设计和难点

客户端跨平台方案选型

目前主流跨平台方案如下所示:



QT 方案老骥伏枥,支持 GPL 协议,除支持普通平台之外还支持 Symbian 平台,开发难度大,库也更丰富。


CEF 和 Electron 目前采用较多,存在亲缘关系。Electron 可采用 JS 接口做 Native 开发,其底层内核可以理解为 CEF。CEF 拥有更强的可定制性,Electron 可自动更新,而 CEF 需自己实现更新机制。Electron 是不支持 Windows XP 的,CEF 虽不太理想但可降级支持 Windows XP。


Flutter 作为 Dart 语言开发的新起之秀,支持较新的操作系统如 Google 的 Fuchsia。由于较新难免存在一些隐患。


其他平台除 Electron 外均使用 C++开发。这是因为 RTC 对延时要求达到了毫秒级,只有 C++这类底层语言才能满足其性能需求。不过,现在新语言如 Go、Rest 等也能实现较好效果。


综合以上,从客户端的选型来说,若团队有 C++高手,我建议选用 CEF,但是若团队偏 Web 前端,Native 开发较弱,则建议选用 Electron。


客户端难点与挑战

客户端目前的挑战分为音频问题和弱网对抗问题。音频问题主要包括无声/声音小,回声和噪音/杂音三类。下图为音频客户端的架构图:



图中底层视频音频引擎和传输均封装了良好的外部接口。因此做 WebRTC 的音视频研发并不需了解底层,从外部 API 入手即可。下图是更详细的 Native RTC 架构图。



上图流程为先通过 ADM 进行信号收集,用 APM 模块(包括 3A 处理)将信号进行编解码,再利用网络发送信号,信号返回后合流、播放。3A 处理即 AEC、ANS、AGC


无声问题需依赖 AGC 做自动化处理。AGC 和设备及其具体参数息息相关,需在算法和底层机制上保持灵活性,面对不同设备种类使用不同的策略。


回声问题需权衡 DTD 和 AEC。DTD 即双讲,要求多人发言时保留人声的交互;AEC 即回音消除,需用线性滤波和非线性处理消除无用的信号。此外,双讲还需通过 CNG 舒适静音生成使听感更逼近真实情景。双讲和回音消除是一对矛盾,无论哪方面如果解决不好,都会非常影响体验。特别在素质教育的一些场景下,例如:音乐课、乐器演奏课等,如果老师和学生一边演奏、唱歌,一边讨论教学,对音频算法处理方面有非常大的挑战,声网目前在音乐教学的音频优化方面有比较大的突破,对相关场景做了更好的优化。


噪音是采用 AI 去噪,需要一个包含典型噪音的特征库进行筛选。然而,降噪模型数据过大会增加包体积,如何平衡好数据包大小和降噪精度也需要更好的工程经验和进一步的方案优化。


弱网对抗能力亦不可或缺,目前的难点包括网络发生变化时如何通过调整码率和帧率缓解变化;在智能路由算法中如何实现最优路径传输;抖动时如何进行缓冲以免网络降级后一味调整延时时间;如何实现多维度质量的实时化评估,和动态调整形成一个闭环……


在弱网对抗中,WebRTC 可对抗 20%~30%的音视频的丢包率,用户体验尚可接受。改造后的 Native RTC,在保证一些额外要求后可实现 70%~80%。


服务器的难点和挑战

下图为服务端的协议栈:



左侧是信令通道协议,现在多采用 WebSocket。WebSocket 为双工双向的控制协议,通过 HTTP 请求进行首次访问,可满足大部分信令传输或即时消息的需求。


我们的媒体通道建立在 UDP 基础上。这两种协议大相径庭,尤其是在高丢包或弱网的情况下,还是 UDP 会更合适。若双通道分开控制在网络比较恶劣的情况下,Websocket(TCP)已经断掉了,但 UDP 还连着,即信令断连,音视频无问题,但做操作会受影响。未来我们希望借助类似 UDP 的协议解决信令通道的问题,提高一致性。


下图为服务端 NAT 穿透架构图:



NAT 网络种类繁多。为节省 IP,用户常在内网中使用内网 IP。此类设备的 RTC 需穿透 NAT。常规情况下,STUN Server 即可解决问题,但某些 NAT 网络无法打通,则需要一个中继:Relay Server。开源的 Server coturn 能同时实现上述两种功能。


开源服务端方案比较

开源的服务器方案众多,按时间排序如下图所示。



Jitsl 是用 Java 写的,支持 Apache 协议,非常活跃。Kurento 支持 Apache 协议,它提出了一个新的项目——OpenVidu。OpenVidu 部分代码也是 Java 写的,试图降低开源的 Server 的接入门槛。Licode 项目由英特尔做了很多的贡献,性能优异但二次改造成本高。


我用过 Kurento 和 Janus。Kurento 的功能和文档都相当出众,文档尤佳,功能介绍极其透彻。Janus 则实为 C 语言开发的 WebRTC 网关,支持 GPR 协议,GitHub Star 数较多,性能也非常好。


此外,Go 语言开发的 Pion 相对较新,结构及模块均清晰明了,新用户采用较多,Star 数也增长很快。


下图是 2018 年,以上方案的早期版本的测试报告:



如图所示,Jitsi 压到约 200 个即出现异常;Janus 较正常,压到了 500;Medooze 较好; mediasoup 的图波动比较,或存在某些问题。


下图为以上各方案面对压力的性能情况。



运维的难点与挑战



我们做了公有云和自建机房的多活,通过自己的路由 Router 将一个物理的空间分成多个区,每个区相对独立,依赖于底层的基础服务。在不同的物理空间之内通过 Update 数据同步实现多活。


以上设计还可以实现一些附加功能,如从容发版,发版时将某个区的流量切走即可;和在某几个特定区做 A/B Test;如果有异常情况,可以从容切换、回滚等。


除此之外,我们还做了容器化部署、自动化运维、监控工具、发布工具、日志系统、全球网络挑战及 Lastmile 策略等。


Lastmile 是由网络复杂性造成的,如家庭 Wi-Fi 2.4G 连接多个设备信道的占用、网络拥塞问题;小区网络运营商限速或跨运营商等问题。此时,可使用 NACK(丢包重传)、FEC(前向纠错) GCC(Google 拥赛控制)以及 PACER 等策略。



质量和自动化测试

自动化测试我们使用的是类似 KITE 的方法。质量指标分为 QoS 和 QoE 两类。QoE 指标分为两类,有参考客观评价方法和无参考客观评价方法。这两类指标都需对照类似 MOS 分的标准质量体系,验证其准确性。

展望 RTC 的未来,如何拥抱变化持续创新

Metaverse(元宇宙)的概念目前火热:即和现实世界平行的虚拟世界,人们可以在其中体验另一种全新的“角色”。有人说 Metaverse 的三大技术基础为 AI、VR/AR/MR 和区块链,但 RTC 也是不可或缺的一环。元宇宙从虚拟走向真实,必须依靠更逼真炫酷的体验和更实时的交互为基础。而 RTC(或者 RTE)作为实时数据的传输的通道,一端连接真实世界的“实体”数字化转型,一端连接虚拟世界的 Metaverse。


在 ROBLOX 游戏中,玩家也可以自行定制开发各种形式的游戏场景。为了提升游戏的沉浸感和仿真度,此时所需的高质量交互体验即为 RTC 未来的发展方向,VRCHAT 同理。


总之,作为 RTC 的自研团队,不能闭门造车,需紧跟时代脉搏和行业发展趋势,乘着时代的东风才能航行得更远、更稳。


嘉宾介绍

董海冰,现任声网 Agora 行业架构师,曾先后就职于平安好学、途牛、沪江等互联网公司,主要负责实时音视频系统架构,基础平台建设,运维监控 & DevOps 等工作。对大型互联网系统的架构设计、分布式、RTC 与 SRE 等都有较深入的理解。


外部链接

coturn:https://github.com/coturn/coturn.git

服务器架构对比:
https://mediasoup.org/resources/CoSMo_ComparativeStudyOfWebrtcOpenSourceSfusForVideoConferencing.pdf