QUIC 在京东直播的应用与实践
一. 前言与背景
国内的互联网直播技术从 2005 年前后兴起,彼时最具代表性的直播产品是由 PPLive 创始人姚欣在华中科技大学就读期间发起的校园直播项目 PPLive。当时的直播技术用的还是基于 windows 系统自带的 mediaplayer 内置的 COM 组件开发的播放器,采用的是 RTSP 协议。受当时的互联网传输带宽及成本限制,PPLive 并没有采用现在比较流行的单播技术,而是采用 P2P 技术分发直播流。国内的直播技术也进入了一段以 P2P 技术为主的时期,其中比较有代表性的就是 PPLive 和 PPStream。用 P2P 技术分发直播流,具有运营成本低的明显优势,每一个参与播放的终端都是一个潜在的数据热点,网络质量随着观看直播流的客户端的增加而增加。但 P2P 技术也有自身的不足,缺乏观众的冷门资源因参与数据共享的客户端稀少而难以保证播放质量,另外 P2P 难以保证 UDP 打洞穿透率、需要下载专用的播放器等都是限制用户数量增长的因素。
P2P 直播分发技术注定是一个过渡性的技术。2005 年以后,由于早期的 HTML 标准尚不完善,各大浏览器存在实现上的差异,被寄予厚望的 HTML5 规范也还尚未定稿,基于 HTML 的视频播放技术也不成熟。彼时,Adobe 公司从 Macromedia 公司收购的网页多媒体插件 flashplayer 在这种情况下脱颖而出。在开发层面,flashplayer 因其优异的多媒体表现力以及完善的开发语言和调试工具,降低了网页播放器的开发门槛。在音视频质量方面,Flashplayer 内置的 On2 公司的 VP6 视频编解码器无论是在编码质量还是在解码效率上在当时都非常优秀,随着 2003 年才定稿的 H.264/AVC 视频编解码器及更高质量的 AAC 音频解码器也很快被内置到 flashplayer 内核,进一步提高了 flashplayer 的音视频能力。在播放器推广层面,基于 flashplayer 开发的播放器文件,能像分发网页一样通过网站服务器下发和更新,这极大地降低了视频网站的推广难度。上述原因,促使 flashplayer 成为当时最好的网页视频播放器内核。在 flashplayer 的技术加持下,视频点播网站如雨后春笋般涌现,尤其在 2006 年 google 收购 youtube 后,网页视频点播网站迎来了爆发,六间房、优酷、土豆等视频网站先后融入巨资,从众多点播网站中脱颖而出。彼时,flashplayer 作为绝大部分视频点播网站统一使用的网页播放器,装机率快速提高,逐步成为事实上的网页多媒体播放器标准。2009 年,随着 Adobe 将 flashplayer 内置的革命性的流媒体传输协议 RTMP(Real-Time Messaging Protocol)规范开放,本就已经方兴未艾的 RTMP 直播技术,进入了发展的快车道。各种基于 RTMP 协议的开源实现陆续出现,涵盖服务器和播放器。由此,互联网直播进入了由 flashplayer 和 RTMP 协议主导的时代。
RTMP 是 flashplayer 原生支持的流媒体传输协议,支持点播和直播模式,经过十多年的大规模应用,已经成为当前国内应用最为广泛的直播协议,各大 CDN 厂商都已经支持。国内技术圈还发展出了 HTTP-FLV 协议,即将 RTMP 中的直播音视频流封装成 FLV 文件流,通过 HTTP 协议传输,这进一步降低了直播技术的接入成本和实现难度。
RTMP 和 HTTP-FLV 都是基于 TCP 的直播协议,TCP 固有的基于拥塞控制的传输策略在需要稳定、大量传输数据的直播场景下显得过于保守,偶发的丢包或网络抖动都会造成数据收发速率的急剧下降,从而造成画面及声音的卡顿,影响直播的质量及体验。而基于带宽和延时预测的 QUIC 传输协议的出现,为直播行业提供了一个提升直播质量和用户体验的新的选项。
二. QUIC 介绍
QUIC(读作“quick”)是一个通用的传输层网络协议,最初由 Google 的 Jim Roskind 设计。该协议于 2012 年实现并部署,2013 年随着实验范围的扩大而公开发布,并向 IETF 描述。虽然长期处于互联网草案(英语:Internet Draft)阶段,但从 Chrome 浏览器至 Google 服务器的连接中超过一半的连接都使用了 QUIC。Microsoft Edge、Firefox 都已支持此协议;Safari 实现了 QUIC,但默认情况下没有启用。QUIC 于 RFC9000 中被正式标准化。
虽然 QUIC 的名称最初是“快速 UDP 互联网连接”(Quick UDP Internet Connection)的首字母缩写,但 IETF 指定的标准中 QUIC 并不是任何内容的缩写。QUIC 提高了目前使用 TCP 的面向连接的网络应用的性能。它通过使用用户数据报协议(UDP)在两个端点之间建立若干个多路连接来实现这一目标,其目的是为了在网络层淘汰 TCP,以满足许多应用的需求,因此该协议偶尔也会获得 “TCP/2”的昵称。
QUIC 与 HTTP/2 的多路复用连接协同工作,允许多个数据流独立到达所有端点,因此不受涉及其他数据流的丢包影响。相反,HTTP/2 建立在传输控制协议(TCP)上,如果任何一个 TCP 数据包延迟或丢失,所有多路数据流都会遭受队头阻塞延迟。
QUIC 的次要目标包括降低连接和传输时延,以及每个方向的带宽估计以避免拥塞。它还将拥塞控制算法移到了两个端点的使用者空间,而不是内核空间,据称这将使这些算法得到更快的改进。此外,该协议还可以扩展前向纠错(FEC),以进一步提高预期错误时的性能,这被视为协议演进的下一步。
三. 京东直播技术简介
京东直播体系从零开始构建,如下图所示,涵盖四大业务模块:推流端、中台源站、直播云 CDN 及播放端。
图 1.京东直播产品体系
从上图可以看出,直播流的端到端传输,中间要经过多个链路。直播数据因数据量大、占用带宽高、传输距离长而符合典型的 Long-Fat(长肥)网络定义。在应用 QUIC 技术之前,京东的直播产品都是使用基于 TCP 的协议(RTMP/HTTP-FLV/HLS 等)进行直播流数据传输,TCP 因其保守的拥堵控制策略,在应对 Long-Fat 网络应用场景时差强人意,QUIC 技术的出现,为优化直播传输质量提供了新的选择。
京东从 2021 年上半年开始研究 QUIC,基于 QUIC ietf v1 版本开发了自研的 QUIC 实现 QUIC-Pro,并最先在京东的直播场景落地。QUIC 在京东直播技术体系的落地过程并非一蹴而就,而是循序渐进的。考虑到直播数据流从 CDN 边缘服务器分发到用户端是最复杂的“最后一公里”问题,因此,我们选择 QUIC 最初的落地场景是直播的分发和播放。
QUIC 落地之前,为了量化直播质量,方便对比优化收益,我们制定了统一的全链路质量监控及数据上报标准,收集推流端、直播源站、直播云 CDN 及播放端等所有环节的跟传输、播放相关的监控数据,并统一上报到数据收集平台进行聚合、分类及统计,在众多质量指标中,选定画面首开时长、卡顿率及播放失败率作为播放质量的重要量化参考指标。
本文将分别从推流端、中台源站、直播云 CDN 及播放端四个部分串烧式地介绍与直播相关的一些技术实践,并重点介绍 QUIC 技术的应用情况及收益。
四. 推流端技术
京东直播支持的推流端包括京东视频 APP,PC 桌面端推流工具以及 web 网页端企业直播工具。京东视频 APP 及 PC 桌面端推流工具除支持真人直播及美颜功能外,还支持数字人直播,数字人直播数据流程如下图所示。
图 2.京东数字人直播 SDK 架构
上图中,VideoSource 和 AudioRecord 分别控制图像和声音数据的输出,当真人直播时,VideoSource 打开 CameraCapturer,采集摄像头图像数据,并送到 Filter 滤镜链条进行美颜等操作,然后进行视频编码并打包发送,音频则通过 AudioRecord 打开 MicrophoneRecord,采集麦克风声音进行录制、编码并打包发送。
当采用数字人直播时,流程经过图中黄色模块,TextureFactory 模拟摄像头运行机制,按帧率设置定期生成空白纹理,纹理经过 VideoSource 进入滤镜链条,滤镜链条中有一个 3DEngineFilter 滤镜,将京东自研的数字人 3D 引擎生成的数字人图像渲染到纹理,然后在屏幕上展示该纹理,同时将纹理上的图像进行编码、打包、发送。数字人的音频,则通过 AudioPlayer 控制音频播放到设备的同时,将音频采样数据输出到 AudioRecord,然后经过编码、打包,并发送出去。
五. 直播源站与 CDN 分发网络
京东直播包括实时音视频源站、实时转码、录制、审核等业务,推流端的实时音视频流都是先推到中台源站,然后再经过处理通过京东直播云 CDN 分发到播放端。中台源站还负责直播连麦相关业务的处理,包括混音、合屏等操作。
图 3.京东中台直播源站低延迟直播服务架构
直播云 CDN 通过京东云对外提供赋能,直播云 CDN 承载了京东主站、京喜等含直播功能的产品的日常直播流分发服务。经过近一年的密切合作,京东直播中台团队和京东直播云 CDN 团队已将共建的 QUIC 直播流分发服务全量部署到所有服务节点。直播云服务流程如下图所示。
图 4.京东直播云 CDN 分发流程图
上图是京东直播云 CDN 对直播流的分发流程图,最左侧是直播源站或直播应用直推直播流到边缘推流集群,经过录制、转码截图、中转集群等中间模块及服务处理,最后转推给第三方 CDN 或经由边缘播放集群分发给播放端。
六. QUIC 服务端设计
当前网络上开源的服务端 QUIC 协议栈实现方案有多种,例如 Chromium QUIC、Lsquic、Nginx 官方 quic、cloudfare quic 等。其中 Chromium QUIC 发展的最早,也相对最成熟。因此 JDQUIC 服务端依托 Chromium QUIC,使用了其 QUIC 协议栈相关源码,服务器框架及其他所有代码则为自研。
6.1.JDQUIC 服务器模式
为尽量减少对现有直播 CDN 分发体系的改造,并保持 QUIC 的可扩展性及高效迭代更新,JDQUIC 服务器采用反向代理模式进行 QUIC 直播流的请求、转换与分发。
图 5.JDQuicServer 工作流程
如上图显示,手机端播放器发送 QUIC 直播流拉流请求到 JDQuic-Server 服务器,JDQuic-Server 服务器将请求格式转换为普通的 http 或 tcp 数据,发送给后端 Web 或者 TCP 服务器,然后接收后端 HTTP-FLV 服务器返回的直播流数据并通过 HTTP/QUIC 协议下发给播放器。整个服务过程无需对后端服务体系作任何修改。
由于 JDQUIC 服务器一般和后端服务器部署在同一机房、甚至同一机器上,两者之间的数据传输延迟基本可以忽略不计。
6.2. JDQUIC 服务端架构
JDQUIC 服务端采用多进程单线程架构。消息驱动采用了 Libevent epoll 模式,QUIC 协议栈则使用了 Chromium QUIC 协议栈相关代码。如下所示:
图 6.JDQuic-Servrer 内部架构
JDQUIC 服务端采用单线程多进程架构,单机多进程采用内核 ebpf 进行负载均衡。
单线程内部采用 Libevent epoll 进行消息监听和分发,TCP UDP Unix domain、http 等多种协议依托 Libevnet 进行收发,同时超时和异步消息也通过 Libevent 架构进行回调。
Libevent 收上来的 UDP 数据包,在 Chromium QUIC 协议栈进行解析,还原出原始 Http 或者裸数据。这些数据经过线程内无锁调度模块,传给后端 Nghttp2 或 tcp udp client 模块,发送给后端服务器。
6.3. JDQUIC 连接迁移
网络的切换在当今移动网络大规模普及的背景下,是经常发生的事情。考虑如下场景,当用户正在户外用移动 4G/5G 网络看着直播的过程中,走到了一个具备 WIFI 网络的地方,连上了可用的 wifi 网络,此时,网络切换便发生了。如果要保证直播连接在网络切换后仍然保持畅通,需要实现一套连接迁移机制。JDQUIC-server 的实现及工作原理,如图 7 所示:
图 7.JDQuic-Server 连接迁移原理
【工作流程】
1.手机端从 4G 网络切到 wifi 网络。
2.手机端网络连到不同的运营商机房(从移动机房切到联通机房)。
3.Ospf 和 nftable 负载分配到一个机器 quic server 实例。
4.Quic server 通过 quic 数据包中的 connection id 中第一个字节,判断数据包该发回哪个机房。
5.Quic server 把数据包转发给原来的机房。
6.原来的机房再负载到正确的 quic 实例。
【说明】
•Ospf 负载: 三层负载均衡服务,硬件负载,效率很高。
•Nftable 单机负载: 操作系统内核级别的负载服务。
•QUIC 服务: quic 服务器,可以将 quic 协议转换为 http 去后端 FMS/SRS 拉流。
•后端 FMS/SRS:直播流媒体/CDN 服务器。
•红色箭头:手机端首次播放直播的拉流路线。
•蓝色箭头:手机端网络切换 WIFI 后进行连接迁移的拉流路线。
6.4. JDQUIC DCID 设计
连接迁移时,联通机房的 quic server 想要找到回源的机器,需要从 quic 数据包的 DestionationConntion id 字段获取机房信息,如下图所示。
图 8.JDQuic-Server CID 扩展设计方案
CID 字段取一个字节来映射机房信息,例如 0x01 表示长春移动,0x02 表示长春联通等。
6.5. JDQUIC ebpf 设计
6.5.1. eBPF 简介
Linux 内核一直是实现监控/可观测性、网络和安全功能的理想地方。 不过很多情况下这并非易事,因为这些工作需要修改内核源码或加载内核模块, 最终实现形式是在已有的层层抽象之上叠加新的抽象。 eBPF 是一项革命性技术,它能在内核中运行沙箱程序(sandbox programs), 而无需修改内核源码或者加载内核模块。
将 Linux 内核变成可编程之后,就能基于现有的(而非增加新的)抽象层来打造更加智能、 功能更加丰富的基础设施软件,而不会增加系统的复杂度,也不会牺牲执行效率和安全性。
图 9.eBPF 原理及工作流程
6.5.2. eBPF 在 JDQuic-Server 中的应用
linux 内核中,通过 ebpf 维护两个映射表,并编写一段 ebpf JIT(即时编译)程序。客户端 QUIC 数据包进来后,ebpf JIT 程序根据 ip 端口、CID 进行 hash,分别访问两个 map 表,来判断需要转发给哪个后端 QUIC 实例。其中,ip 和端口为 UDP 协议数据包的字段,包括源 IP、目的 IP、源端口、目的端口(合称四元组),如图所示。
图 10.JDQuic-Server 内部 ebpf 负载均衡原理
七. QUIC 技术收益
QUIC 协议基于带宽瓶颈预测及环路延时预测的传输控制算法,相比 TCP 的基于网络拥塞的控制算法,在抗网络抖动、提高网络传输速率方面有显著优势。根据 QuicPro 在线上 Android 应用内的直播场景中的使用情况统计数据显示,直播卡顿率较 TCP 由 1.43%降为 1.14%,降幅为 20%,首开时间较 TCP 的 949 毫秒降为 659 毫秒,降幅为 30.5%,如下图所示:
图 11.TCP 与 QUIC 分别在直播卡顿率及首开时间上的对比
八. 结语
京东直播经过 4 年多的发展,技术上无论是服务架构还是播放协议都经过了多轮迭代,截至本文成文,仍在进行迄今为止最大规模的改造升级,涉及全链路的协议升级与架构优化。协议上,将原有的基于 TCP 的信令、推流、分发、播放等环节升级为 QUIC 协议,在服务架构上,进行推流及媒体服务边缘化改造,在分发上,中台与京东云直播 CDN 兄弟部门共建低延迟分发网络,我们共同的目标是提升传输质量、降低卡顿率的同时,将直播端到端的延迟降低到 2 秒甚至是 1 秒以内。
版权声明: 本文为 InfoQ 作者【京东科技开发者】的原创文章。
原文链接:【http://xie.infoq.cn/article/0e2540f97cd82ab235e7fe494】。文章转载请联系作者。
评论