聊聊QUIC协议的发展

LiveVideoStack 2021年12月29日

作者 | 王盛 策划 | 包研、Alex 编辑 | Alex


QUIC 年终盘点 #001#


QUIC(Quick UDP Internet Connections,快速UDP互联网连接)是一种新的“更快”的通用网络传输协议。相比于TCP和TLS,QUIC提供了许多改进来提升网络传输的性能。随着QUIC协议的标准化,QUIC之上的HTTP/3协议已经被众多浏览器所支持,其中包括Chrome、Microsoft Edge(Chrome内核版本)、Firefox和Safari,除了浏览器,也有不少客户端App也开始支持和使用HTTP/3。本篇文章就和大家一起聊聊QUIC协议的发展历程,和我认为的QUIC未来发展趋势。

QUIC协议的发展

聊聊QUIC协议的发展


事实上,我们现在谈论的QUIC协议有两个协议同名:“Google QUIC”(简称gQUIC)和“IETF QUIC”(简称iQUIC)。gQUIC是由Google工程师们在2012年设计的原始协议,2013年Google公开了QUIC协议,同年也将此协议提交给IETF。这与SPDY和HTTP/2协议的发展历程如出一辙,先由Google公司设计和试验,在性能有提高的情况下提交给IETF工作组进行标准化。

2015年6月,一份QUIC的Internet Draft提交到IETF组织进行标准化,同年IETF的QUIC工作组也因此成立[1]。

2018年10月,IETF的HTTP工作组和QUIC工作组联合声明了HTTP/3,也就是QUIC之上运行的HTTP协议,但此时HTTP/3的具体标准尚未定稿。

2021年5月,IETF宣布了QUIC的标准RFC9000[2],同时RFC9000由RFC8999[3](Version-Independent Properties of QUIC),RFC9001[4](Using TLS to Secure QUIC)和RFC9002[5](QUIC Loss Detection and Congestion Control)所支持。

至此,QUIC协议的完整标准已经形成,iQUIC与当初的gQUIC已有相当大的不同,可以完全将其视为一个单独的协议。从数据包的格式、握手方式和HTTP映射,iQUIC改进了当初gQUIC的设计,这也得益于许多组织和个人的开放协作,他们的共同努力让互联网变得更快、更安全。

作者注:本文后续如未加特殊说明,都是在描述iQUIC。

QUIC协议的现状


QUIC协议的诞生与今天的互联网应用场景和传输性能密切相关。在互联网和HTTP发展的过程中,HTTP底层协议大体上来说基本没变。但是,随着海量移动设备推高互联网流量,越来越多的应用场景需要低延迟、高吞吐、应用QoS感知的网络传输等,原来的HTTP协议在提供流畅、高效的Web访问方面越来越难以满足应用需求。

QUIC的一切特性始于“构建在UDP之上”


“构建在UDP之上”意味着可以不关心内核或者不用深入了解内核的开发,也可以灵活地调整可靠传输机制和拥塞控制算法等,这极大地方便了各种对传输QoS敏感的应用,比如实时音视频传输、在线游戏等。QUIC的主要特性如下所示:

  • 选择UDP也能让QUIC协议不依赖网络中间设备Middle-Boxes做调整。

  • TCP协议的开发、调试、观测的困难问题也会迎刃而解,无需通过复杂的BPF(Berkeley Packet Filter)来采集和调试协议栈程序,只需在用户态部署简单的数据收集程序。

  • 应用程序的崩溃问题也不至于影响系统内核,而且可以留足崩溃现场做后续分析。

  • 用户态有更多的程序库帮我们实现更复杂、更全面的策略,比如自适应CC(Congestion Control)算法。

  • 利用UDP的数据包无序列依赖,QUIC多数据流之间多路复用,无队首阻塞问题,并且各自有独立的流控(Flow Control)。

  • 耦合TLS1.3实现0-RTT建连,连接复用。

  • 用户态实现和网络五元组无关的连接标识ID,ConnectionID,实现连接迁移,以及后续的多路径(Multipath QUIC)。

QUIC的使用量稳步提升中


随着QUIC v1版协议标准的出现,越来越多的网站开始使用QUIC流量,根据W3Techs[6]的统计显示,目前大概有23.8%的网站使用了HTTP/3。

聊聊QUIC协议的发展


浏览器支持情况

  • Chrome和Opera都支持gQUIC和iQUIC。

  • 2021年5月,Firefox在Firefox Nightly版本中开始支持QUIC。

  • 2020年4月,Apple在WebKit引擎进行了试验性的QUIC支持,并正式在macOS Big Sur和iOS 14上的Safari 14中支持,但是需要手动打开HTTP/3。

客户端支持情况

  • Cronet是最早支持QUIC的客户端库,目前有比较多的客户端引用了Cronet库,其中包括Google Play Services、YouTube、Gmail等。

  • cURL 7.66版本(2019年9月发布)也支持了QUIC,不过cURL引用的QUIC协议栈是Cloudflare RUST开发的quiche开源库。

  • 2020年10月,Facebook声称其下各APP也都支持了QUIC,包括Instagram,并且有75%的流量使用了QUIC协议。

  • Uber App也支持了QUIC协议。

服务端支持情况

  • 2016年和2017年开始就已经有不少公开的QUIC服务端实现了,其中Google开源了其原型服务端源码:https://github.com/google/quiche/blob/main/quic/tools/quic_server_bin.cc。

  • 开源Caddy Server也有一套基于Go语言实现的QUIC协议栈,能够提供QUIC服务。

  • 2017年开始,LiteSpeed在其WebADC(Load balancer)和LiteSpeed Web Server产品上也支持了QUIC协议。

  • 2018年开始,Facebook和Cloudflare也开始在其服务端支持QUIC协议。

  • 2021年开始,微软在其Windows Server 2022和SMB上开始支持了QUIC协议,并开源了其协议栈MsQuic。

  • 随后,Citrix的ADC(Application Delivery Controller)和NetScaler产品也支持了QUIC协议。

部分开源QUIC协议栈列表[7]

聊聊QUIC协议的发展


阻碍QUIC发展的一些问题

集成难度

无论是在客户端还是服务端,QUIC协议的集成并非一件易事。如果当前使用的网络不支持QUIC,意味着我们需要修改应用程序来适配网络库的调整。这往往并不是应用迭代的出发点。

下面让我们来看看客户端和服务端在集成QUIC协议时需要考虑的问题:

客户端

  • 应用适配成本和收益之间的权衡。

  • 过渡期可能还需要新旧网络库都存在,方便降级容错,增加应用体积。

  • 不同的QUIC库的接口并不统一,不像Socket统一接口具备移植性。

服务端

  • 网络事件模型需要适配QUIC协议栈做调整,同时还要考虑和TCP的兼容。

  • 后端架构面临调整,4层Load Balancer是否支持QUIC,HTTP/3的QUIC流量如何换成HTTP/1转给Backend Service。

  • 需要考虑到多Region、多节点之间的QUIC连接复用和连接迁移。

  • 服务端QUIC流量的能耗比,如何做到和TCP一样的能耗性能。

聊聊QUIC协议的发展


QUIC协议栈性能

对比已经发展了三十多年的TCP协议,新兴的QUIC协议在协议栈实现的工程上还有很多优化的事情要做,根据Google 2017年公开的数据可以看到[8],当时QUIC同等流量的CPU消耗是TCP的2倍之多。QUIC协议栈的性能痛点主要有:

  • UDP数据包收发性能

  • 数据装包、拆包处理性能

  • 数据包解析性能

  • ACK处理性能

  • 加、解密性能

  • 其他流程处理的性能:数据包Pacing、CC算法、内存使用等

UDP数据包性能

UDP数据包在内核接收发送上一直没有得到和TCP数据包一样的优化待遇,UDP收发占据了QUIC协议栈比较大的消耗。

  • 原始的sendto/write的UDP Socket接口性能很弱。

  • 批量收发数据sendmsg/sendmmsg提升不够明显。

  • 内核GRO/GSO可以提升性能,但还不够。

  • 内核XDP或者DPDK可大幅提升性能,但程序改造量极大。

  • 硬件NIC Offload UDP收发能终极优化,同样程序改造量极大。

聊聊QUIC协议的发展


上图是Google在2020年统计的QUIC能耗情况[8]:相比于TCP/SSL,QUIC有20%的额外消耗。B站内部也差不多在这个水平,不过相信随着更多的优化方案的实施,QUIC和TCP的流量能耗会趋于一致。

UDP被运营商QoS限制

据我了解,结合我们自己部署的QUIC协议运行情况来看,国内运营商确实会对UDP流量做些QoS的限制,但是能够被QoS限制的比例微乎其微,可以完全忽略。运营商这么做主要基于两个原因:

  1. UDP流量五元组在NAT状态上连接老化的时间控制不够精确,时间设置太长会破坏低频通信的UDP连接,太短会导致UDP连接消耗比较多的设备性能。一般会选择一个折中的经验值,这就会伤害一些特定场景的UDP流量了。

  2. 运营商设备上包分类的优先级队列对于UDP五元组的管理比较困难,因为UDP的五元组会频繁变动,只能眼睁睁看着UDP流量挤占各级队列,却没办法实施精确地控制。一般来说,运营商会在特定时间段或者特定负载情况下对UDP流量做全局限制。

调试QUIC协议


随着QUIC协议越来越多的使用,调试QUIC协议的方法也逐渐形成了标准——qlog(目前还是草案[9])。我们可以把qlog理解成一种和wireshark类似的抓包工具,但是是嵌入到协议栈内部的抓取数据包关键信息的一套协议,具体可参考qlog草案。qvis则是qlog的一套前端工具[10],用来帮助工程师调试调优QUIC协议交互过程。

聊聊QUIC协议的发展


聊聊QUIC协议的发展


其实qlog能做的不仅这些,我们可以结合大数据分析和机器学习模型,在海量的QUIC传输数据里进行分析,能够做到网络故障的自动定位、传输算法调优和网络特征工程等,具体可参考[11]开源项目,本文不做详述。

QUIC协议的未来


虽然QUIC协议是因为HTTP/3而提出来,但我认为,QUIC的未来应该不仅限于HTTP/3。QUIC已具备的一些特性,不仅可以让现有的Web应用运行得更快更安全,还能适配到更多应用场景上,比如IoT、VR、音视频会议等。基于QUIC协议之上,工程师们可以定制开发更多场景的应用,同时也让QUIC协议具备的能力更加完善。

从我个人出发,结合B站的业务场景,我主要关注了QUIC协议在音视频传输领域的未来发展:QUIC Datagram[12]和QUIC Multipath[13]。

QUIC Datagram——QUIC的非可靠数据报文传输扩展

QUIC v1(RFC9000)提供了一个安全、可靠、多路复用的传输方案,QUIC Stream数据流是QUIC主要数据传输的载体,可靠传输是其需要保证的基本功能。

但是有些应用场景并不需要严格的可靠传输,例如实时音视频、在线游戏等。现在这些场景有些是直接基于自定义UDP或者WebRTC实现的。自定义UDP实现传输层功能的话比较麻烦,工程量大,有时候为了安全考虑还需要加上DTLS支持,而WebRTC的建立数据传输通道流程也比较繁琐,WebRTC主要场景是为了P2P设计的,长远来看并不适合客户端服务端的场景。

因此,QUIC支持不可靠数据传输能够让QUIC协议的应用范围更广,适合更多的应用场景,而且QUIC之上的不可靠数据传输能够很好地复用QUIC的安全特性。

QUIC Datagram特点

  • 同一QUIC连接里面可以同时包含可靠Stream传输和不可靠数据传输,它们可以共享一次握手信息,分别可以作用于TLS和DTLS,可降低握手延迟。

  • QUIC在握手上比DTLS更加精准,它对每个握手数据包加上了超时重传定时器,能够快速感知握手包的丢失和恢复。

  • QUIC Datagram的不可靠传输也可以被ACK,这是一个选项,如果有ACK,可以让应用程序感知到QUIC Datagram的成功接收。

  • QUIC Datagram也适用于QUIC的CC。

这些特性能够让实时音视频流、在线游戏和实时网络服务等应用的传输得到极大的效率提升。

WebTransport呼之欲出


聊聊QUIC协议的发展


WebTransport是一个框架型的协议[14],该协议使客户端与远程服务器端在安全模型下通信,并且采用安全多路复用传输技术。注意:WebTransport是一个框架,在它下面是实际的协议,框架提供了一个一致的接口,因此它由一组可以安全地暴露给不受信任的应用程序的协议以及一个允许它们互换使用的模型组成。它还提供了一组灵活的功能,为我们提供了可靠的单向和双向流以及非可靠的数据报文传输。

QUIC Multipath


聊聊QUIC协议的发展


QUIC Multipath多路径传输,简言之就是用多个物理网络路径来传输数据,可以同时使用WIFI、LTE/4G或者IPV4/IPV6。随着音视频的消费码率越来越高,对网络连接的吞吐能力要求越来越高,单路径的网络情况开始捉襟见肘,MP-QUIC可以发挥比较大的作用。比如在超高清、超高码率视频8K、VR等场景。

MP-QUIC基本思路是: 用多个网络路径来组成一个QUIC连接进行数据传输,MP-QUIC其实也是对连接迁移特性的一次拓展,协议标准也在草案阶段[13]。用多个网络路径实现一个QUIC连接看似简单,其实实现上有很多事情需要考虑:

  • 异构网络

  • 数据包冗余分配和流量成本之间的ROI

  • 多路径调度策略

聊聊QUIC协议的发展


协议标准目前只规定了多路径实现的机制,也就是多个单向的UniFlow组成QUIC连接,多路径调度和冗余包策略都需要额外单独实现。不过随着业务场景需求的展开和协议标准的正式推出,我相信MP-QUIC在音视频传输上的应用会越来越多。

参考文献


[1] QUIC Wiki: https://en.wikipedia.org/wiki/QUIC 

[2] RFC9000: https://datatracker.ietf.org/doc/html/rfc9000 

[3] RFC8999: https://datatracker.ietf.org/doc/html/rfc8999 

[4] RFC9001: https://datatracker.ietf.org/doc/html/rfc9001 

[5] RFC9002: https://datatracker.ietf.org/doc/html/rfc9002 

[6] W3Techs HTTP/3 Usage Statistics: https://w3techs.com/technologies/details/ce-http3 

[7]

QUIC Workgroup Implementations List: 

https://github.com/quicwg/base-drafts/wiki/Implementations 

[8]

QUIC CPU Performance: https://conferences.sigcomm.org/sigcomm/2020/files/slides/epiq/0%20QUIC%20and%20HTTP_3%20CPU%20Performance.pdf 

[9]

QLog: https://datatracker.ietf.org/doc/html/draft-ietf-quic-qlog-main-schema-01 

[10]

Debugging QUIC and HTTP3 with QLog: https://www.researchgate.net/publication/342783373_Debugging_QUIC_and_HTTP3_with_qlog_and_qvis 

[11]

QLog&Qvis Tools: https://github.com/quiclog 

[12]

QUIC Datagram: https://datatracker.ietf.org/doc/html/draft-ietf-quic-datagram-06 

[13]

QUIC Multipath:

https://datatracker.ietf.org/doc/draft-deconinck-quic-multipath/ 

[14]

W3C WebTransport: https://www.w3.org/TR/webtransport/ 

作者简介:王盛,B站视频云CDN系统负责人。多年音视频后端开发和网络传输开发的经验,参与了B站视频云平台从零到TB级的建设。主导研发了B站千万级DAU的音视频分发网络,精通各类网络传输协议和各场景敏感的网络算法调优。


还可输入800
全部评论
作者介绍

王盛

哔哩哔哩

高级工程师

文章

粉丝

视频

相关文章
阅读排行
  • 2周
  • 4周
  • 16周