写点什么

深入解析 QUIC 协议

作者:拍乐云Pano
  • 2022 年 1 月 06 日
  • 本文字数:3313 字

    阅读完需:约 11 分钟

深入解析QUIC协议

QUIC(Quick UDP Internet Connection)是 Google 提出的一个基于 UDP 的传输协议,因其高效的传输效率和多路并发的能力,已经成为下一代互联网协议 HTTP/3 的底层传输协议。除了应用于 Web 领域,它的优势同样适用于一些通用的需要低延迟、高吞吐特性的传输场景。本文从 QUIC 的由来和优势出发,分享实际项目中需要考虑的问题和解决思路,通过测试对比 QUIC 和 TCP 的实际传输能力,希望有助于大家理解和实践 QUIC 协议。



PART 01 为什么需要 QUIC?

众所周知,HTTP 从最初的 HTTP/0.9,经历了 HTTP/1.x,HTTP/2 到最新的 HTTP/3 这几个大的更新版本。在 HTTP/3 版本之前,HTTP 底层都是用 TCP 传输数据,而伴随着移动互联网的发展,网络交互场景越来越丰富并要求及时性,传统 TCP 固有的性能瓶颈越来越不能满足需求,原因有以下几点:

建立连接的握手延迟大

HTTPS 包含两个握手:1)TCP 三次握手,1 个 RTT;2)TLS 握手,2 个 RTT。完整握手总共需要 3 个 RTT,对于直播等需要首帧秒开场景,握手延迟太大。

多路复用的队首阻塞

以 HTTP/2 多路复用为例,多个数据请求作为不同的流,共用一条 TCP 连接发送,所有的流应用层都必须按序处理。若某个流的数据丢失,后面其他流的数据都会被阻塞,直到丢失的流数据重传完成其他流才能被继续传输。即使接收端已经收到之后流的数据包,HTTP 协议也不会通知应用层去处理。

TCP 协议的更新滞后

TCP 协议是实现在操作系统内核内,但是用户端的操作系统版本升级非常困难,很多老旧的系统像 WindowsXP 还有大量用户使用,因此 TCP 协议的一些更新很难被快速推广。

正是考虑到以上的这些问题,QUIC 在应用层之上基于 UDP 实现丢包恢复,拥塞控制,加解密,多路复用等功能,既能优化握手延迟,同时又完全解决内核协议更新滞后问题。

PART 02 QUIC 的优势

这里列举下 QUIC 的主要优势。

握手建连更快

QUIC 建连时间大约 0~1 RTT,在两方面做了优化:

1)传输层使用了 UDP,减少了 1 个 RTT 三次握手的延迟。

2)加密协议采用了 TLS 协议的最新版本 TLS 1.3,相对之前的 TLS 1.1-1.2,TLS1.3 允许客户端无需等待 TLS 握手完成就开始发送应用程序数据的操作,可以支持 1 RTT 和 0RTT。

对于 QUIC 协议,客户端第一次建连的握手协商需 1-RTT,而已建连的客户端重新建连可以使用之前协商好的缓存信息来恢复 TLS 连接,仅需 0-RTT 时间。因此 QUIC 建连时间大部分 0-RTT、极少部分 1-RTT,相比 HTTPS 的 3-RTT 的建连,具有极大的优势。

避免队首阻塞的多路复用

QUIC 同样支持多路复用,相比 HTTP/2,QUIC 的流与流之间完全隔离的,互相没有时序依赖。如果某个流出现丢包,不会阻塞其他流数据的传输和应用层处理,所以这个方案并不会造成队首阻塞。

支持连接迁移

什么是连接迁移?举个例子,当你用手机使用蜂窝网络参加远程会议,当你把网络切换到 WLAN 时,会议客户端会立马重连,视频同时出现一瞬间的卡顿。这是因为,TCP 采用四元组(包括源 IP、源端口、目标地址、目标端口)标识一个连接,在网络切换时,客户端的 IP 发生变化,TCP 连接被瞬间切断然后重连。连接迁移就是当四元组中任一值发生变化时,连接依旧能保持,不中断业务。QUIC 支持连接迁移,它用一个(一般是 64 位随机数)ConnectionID 标识连接,这样即使源的 IP 或端口发生变化,只要 ConnectionID 一致,连接都可以保持,不会发生切断重连。

可插拔的拥塞控制

QUIC 是应用层协议,用户可以插拔式选择像 Cubic、BBR、Reno 等拥塞控制算法,也可以根据具体的场景定制私有算法。

前向纠错(FEC)

QUIC 支持前向纠错,弱网丢包环境下,动态的增加一些 FEC 数据包,可以减少重传次数,提升传输效率。

PART 03 基于 QUIC 的服务架构

实际项目在应用 QUIC 之前,首先要对整体服务架构做一些宏观上的思考,对下面的问题进行一定的思考后,再去考虑项目本身的细节,可以规避一些技术弯路。

哪些链路需要提升传输效率?

TCP 的性能瓶颈主要体现在具有数据丢包的网络,由于 TCP 的 AIMD(加性增、乘性减)的拥塞避免策略,网络上出现少量丢包,TCP 拥塞控制算法会指数级降低传输速率,导致其无法有效利用带宽。对于一些比较理想的网络,比如局域网内,TCP 与 QUIC 的传输能力相当,传输速率受限于实际带宽,引入 QUIC 反而增加了复杂度。

如何兼容老的客户端?

新的架构不能影响老的客户端,因此需要同时支持 TCP 和 QUIC。

如何实现连接迁移?

用户在 4G 和 WIFI 之间切换,如何实现连接迁移,保证业务层不中断?

QUIC 是否会带来一些弊端,如何解决?

新事物产生往往会伴随新的问题,QUIC 实现在内核之上的应用层,用 UDP 替代 TCP 传输,也带来了一些问题:

(1)国内运营商针对 UDP 做 QOS 限速和丢包,一些企业的局域网防火墙有时候会禁用 UDP 协议,导致网络 UDP 传输低效不可用。

(2)QUIC 的协议栈运行在用户态,同时因为协议的复杂度,对 CPU 的消耗会比 TCP 高不少,实际实现时如何尽可能的减少 QUIC 对服务器性能的影响?

(3)UDP 的报文长度受限于 MTU,对于大块数据,QUIC 在应用层切成大量的小包,收发会造成大量的系统调用 sendmsg/recvmsg,因此 QUIC 的网络吞吐相比 TCP 有很大劣势。Linux 系统提供了多种优化手段:1)支持批量发送函数 sendmmsg,多个 UDP 报文,通过一次系统调用完成发送;2)开启内核 GRO/GSO,在网卡驱动完成拆包和组包;3)网卡支持硬件 UDP GSO offload。

考虑到以上问题之后,一般 QUIC 服务可以类似按照下图的架构设计。

加速链路

对以下两段链路使用 QUIC 加速:

1)最后一公里:因受 wifi 设备性能、蜂窝网络信号覆盖范围强弱等因素影响,用户终端的最后一公里网络能力参差不齐,是比较容易出现弱网的一段链路。

2)数据中心间级联:数据中心之间的数据一般会走骨干网,但在一些流量高峰时段,可能会出现网络拥塞,比较容易出现数据丢包,延时加剧。

双链路备份

客户端一般会同时支持 TCP 和 QUIC 两种传输通道,互为备份,根据两条链路的实际状况(RTT、丢包等)智能选择最优传输通道。

连接迁移的实现

如前文所述,QUIC socket 采用 UDP 收发数据,一个连接用一个 ConnectionID 唯一标识,无论用户在蜂窝网络与 WLAN 之间如何切换,只要数据包中的 ConnectionID 不变,服务端可以将不同的四元组关联到同一个连接上下文,从而避免出现断网重连。但是实现无缝的连接迁移困难并不小,为了实现高并发,服务端一般都会采用多线程,多进程的架构,负载均衡根据四元组将连接 ConnectionID 关联到特定的运行环境(线程或进程),连接迁移大概率会导致缓存的连接上下文失效。以下图多线程的设计举例,设想 CID1 连接迁移发生时,用户源 IP 和端口由 A 变成 C,socket 绑定的线程由 1 迁移到 2,因线程 2 查找不到 CID1 连接的上下文,导致连接迁移失败。


上图只是多线程的架构,我们可以想办法把新的 socket 重新 bind 回线程 1。如果是多进程架构,负载均衡会寻址到不同的服务器上,如何将连接重新寻址到原始服务器?

业内一般的解决思路借鉴了雪花算法,在建连完成就给 Server 的 destination ConnectionId 打上初始服务器的地址标记,根据这些标记信息(集群 ID+机器 ID+线程 ID),让新的服务器寻址到初始的服务器,后续数据再透明转发给初始服务器,整个过程仅增加了一次转发动作,对用户没有任何感知。


PART 04 传输时延测试

建连时延

上图可以看到建连有将近 50%的提升,QUIC 节省了 2-RTT 时间,对于一些 RTT 高网络,效果更显著。

丢包时延

为了对比 TCP 和 QUIC 在丢包网络下的表现,分别对 5%、15%、30%的丢包率场景做了对比测试。每一种场景,进行 1000 次测试,每次测试发送 10KB 数据,统计最终落在指定时延以下的概率。最终的结果参考下图,横坐标表示时延,纵坐标用百分比表示指定时延下的样本数量,曲线收敛速度越快,落在较低时延范围的样本数量越多,所以时延表现越好。

5%丢包下,200ms 内传输完成的测试样本,QUIC 占 95%,TCP 占 78%,QUIC 比 TCP 提升了 17%左右。

15%丢包下,200ms 内传输完成的测试样本,QUIC 占 90%,TCP 占 50%,QUIC 比 TCP 提升了 90%左右。


30%丢包下,200ms 内传输完成的测试样本,QUIC 占 62%,TCP 占 22%,QUIC 比 TCP 提升了 300%左右。


总结起来,QUIC 相比 TCP 的弱网丢包下的延时提升比较比较明显,丢包率越高,提升越明显。

PART 05 总结

本文对 QUIC 实践中遇到的主要问题和相应解决思路做了一些分享,实际项目应用时,由于需求的多样性、现有服务架构的差异,需要因地制宜,将 QUIC 的一些好的特性以比较优雅地姿势应用。

关注拍乐云 Pano,了解更多音视频相关技术、产品实践!

发布于: 刚刚
用户头像

拍乐云Pano

关注

Be Sharp,be simple 2020.06.28 加入

我们是一家由顶级音视频团队构建的实时通信Paas云服务公司,在音视频领域拥有超过二十年的技术积累。 我们通过提供极简、稳定和安全的SDK服务,让你的应用轻松实现音视频通话、互动白板、互动直播等能力。

评论

发布
暂无评论
深入解析QUIC协议