QUIC(Quick UDP Internet Connection)传输层协议:设计和因特网规模的部署
如果只能记住一句话
QUIC:基于 UDP 在用户空间实现了 0-RTT 握手和显式的确认重传
摘要
QUIC 是一种从头开始设计的加密,多路复用和低延迟传输协议,旨在提高 HTTPS 流量的传输性能,并实现快速部署和持续发展的传输机制。
QUIC 已在 Google 的数千台服务器上进行了全球部署,用于为包括广泛使用的 Web 浏览器(Chrome)和流行的移动视频流应用程序(YouTube)在内的各种客户端提供流量。
本文描述了开发新传输工具的动机,指导我们设计的原则,用于对 QUIC 进行迭代实验的 Internet 规模的流程,各种服务的性能改进以及在全球部署 QUIC 的经验。
本文将分享从部署中学到的有关传输设计和 Internet 生态系统的经验和教训。
一、介绍
QUIC 是一种全新设计的传输工具,旨在从根本上提高HTTPS流量的性能,并实现快速部署和传输机制的持续发展。
特征简述:
- QUIC 取代了大多数传统的 HTTPS 堆栈:HTTP/2,TLS 和 TCP。
- 开发了 QUIC 作为以 UDP 为基础的用户空间传输。
- 在用户空间中构建 QUIC 有助于将其部署为各种应用程序的一部分,并使迭代更改能够在应用程序更新时间尺度上发生。
- QUIC 是一种加密的传输方式:对数据包进行身份验证和加密。
- QUIC 通过使用轻量级的数据结构抽象流来消除行首阻塞延迟,这些流在单个连接中进行多路复用,因此单个数据包的丢失仅会阻塞该数据包中的数据流。
居然可以在应用层做传输和拥塞控制?有点想知道接下来会写什么。
QUIC 已被广泛部署:目前,它占 Google 总出口流量的 30% 以上(以字节为单位),因此估计占全球 Internet流 量的7%。
我们在 2013 年启动了 QUIC 的早期版本作为实验。在对该协议进行了几次迭代之后,并根据我们三年的部署经验,成立了一个 IETF 工作组对其进行标准化。
标准化成协议,提供接口规范和文档说明。
参考:QUIC 协议标准
二、动机
Web 延迟仍然是改善用户体验的障碍,而尾部延迟仍然是扩展Web平台的障碍。同时,互联网正迅速从不安全的流量转移到安全的流量,这增加了延迟。
- 协议壁垒:简单的协议更改预计将花费长达十年的时间才能看到显著的部署。
- 实现壁垒:TCP 通常在操作系统(OS)内核中实现。与操作系统的耦合限制了简单的网络更改的部署和迭代速度。
- 握手延迟:大多数 Web 事务都是短传输,受 TCP 和 TLS 的握手时延的影响很大。
- 行头阻塞延迟:TCP 的字节流抽象阻止了应用程序控制其通信的帧,并对必须等待重新传输之前丢失的 TCP 段的应用程序帧征收“等待时间税”。
QUIC 对传输头进行加密,并在 UDP 上构建传输功能,从而避免了对供应商和网络运营商的依赖,并将传输部署的控制权转移到直接受益于它们的应用程序中。
在应用层使用 UDP 协议做传输和拥塞控制。从最近看的好多论文来看,TCP 好像已经老了。
三、设计和实现
QUIC 旨在满足多个目标,包括可部署性,安全性以及减少握手和行头阻塞延迟。
- QUIC 协议将其加密和传输端口握手相结合,以最小化设置 RTT。它通过为每个请求提供自己的流来多路复用单个请求上的多个请求/响应,从而使任何响应都不会被另一个阻止。
- 它对数据包进行加密和认证,以避免中间盒篡改并限制协议的僵化。
- 通过使用唯一的数据包编号避免重传歧义,以及在 ACK 中使用显式信令进行准确的RTT测量,它可以提高丢失率恢复。
- 通过用连接 ID 来标识连接而不是 IP/端口5元组,允许连接跨 IP 地址更改进行迁移。
- 它提供流控制以限制在慢速接收器上缓冲的数据量,并通过使用流控制限制来确保单个流不会消耗所有接收器的缓冲区。
我们的实现提供了一个模块化的拥塞控制接口,用于与各种控制器进行实验。
面向协议编程,基于 RPC 协议的微服务架构成为了软件开发的主流。
3.1 连接建立
QUIC 依靠组合的加密和传输握手来建立安全的传输连接。握手成功后,客户端会缓存有关源的信息,在到相同源的后续后续连接上,客户端可以建立加密连接,而无需其他往返行程,并且可以在客户端握手数据包之后立即发送数据,而无需等待服务器的答复。
QUIC 提供了专用的可靠流来执行加密握手。本节概述了 QUIC 加密握手的机制,以及它如何促进零往返时间(0-RTT)连接的建立。
1. 初始握手
最初,客户端没有有关服务器的信息,因此,在尝试进行握手之前,客户端会向服务器发送不正确的客户端问候(CHLO)消息以引发拒绝(REJ)消息。
REJ消息包含:
- 服务器配置
- Diffie-Hellman 公开值
- 认证服务器的证书链
- 使用来自链的叶证书的私钥对服务器配置进行签名
- 源地址令牌(一个经过身份验证的加密块,其中包含客户端的公共可见 IP 地址)
客户端在以后的握手中将此令牌发送回服务器,以表明其 IP 地址的所有权。客户端收到服务器配置后,它将通过验证证书链和签名来对配置进行增值。然后,它将发送完整的 CHLO,其中包含客户端的Diffie-Hellman 公开值
Diffie-Hellman:一种确保共享KEY安全穿越不安全网络的方法,它是 OAKLEY 的一个组成部分。Whitefield 与 Martin Hellman 在1976年提出了一个奇妙的密钥交换协议,称为 Diffie-Hellman 密钥交换协议/算法(Diffie-Hellman Key Exchange/Agreement Algorithm)。这个机制的巧妙在于需要安全通信的双方可以用这个方法确定对称密钥,然后可以用这个密钥进行加密和解密。但是注意,这个密钥交换协议/算法只能用于密钥的交换,而不能进行消息的加密和解密。双方确定要用的密钥后,要使用其他对称密钥操作加密算法实现加密和解密消息。
Oakley 算法是对 Diffie-Hellman 密钥交换算法的优化,它保留了后者的优点,同时克服了其弱点。Oakley 算法具有五个重要特征:它采用称为 cookie 程序的机制来对抗阻塞攻击;它使得双方能够协商一个全局参数集合;它使用了现时来保证抵抗重演攻击;它能够交换 Diffie-Hellman 公开密钥;它对 Diffie-Hellman 交换进行鉴别以对抗中间人的攻击。
2. 最终/重复握手
如果握手成功,则服务器将返回服务器问候(SHLO)消息。该消息使用初始密钥进行加密,并包含服务器的临时 Diffie-Hellman 公开值。
有了对等方的临时公共价值,双方都可以计算用于连接的最终或前向安全密钥。发送 SHLO 消息后,服务器立即切换到使用前向安全密钥加密的发送数据包。
收到 SHLO 消息后,客户端切换到发送使用前向安全密钥加密的数据包。
因此,QUIC 的加密提供了两个级别的保密性:
- 使用初始密钥对初始客户端数据进行加密。
- 初始密钥提供类似于会话票据的 TLS 会话恢复的保护
- 使用前向安全密钥对后续客户端数据和所有服务器数据进行加密。
- 前向安全密钥是临时密钥,可以提供更大的保护。
客户端现在可以将初始密钥加密的数据发送到服务器,而不必等待服务器的响应。
最终,源地址令牌或服务器配置可能会过期,或者服务器可能会更改证书,从而导致即使客户端发送了完整的 CHLO,握手失败。在这种情况下,服务器将回复 REJ 消息,就像服务器已收到早期的 CHLO 一样,握手也从那里进行。
3. 协议协商
QUIC 客户端和服务器在建立连接期间执行版本协商,以避免不必要的延迟。
QUIC 客户端在连接的第一个数据包中提议一个用于连接的版本,并使用提议的版本对其余的握手进行编码。
如果服务器不兼容客户端选择的版本,它将通过将版本协商数据包发送回带有服务器支持的所有版本的客户端来强制版本协商,从而导致建立连接之前的往返延迟。否则为零往返时间(0-RTT)连接。
3.2 流量多路复用
应用程序通常在 TCP 的单字节流抽象中对数据单元进行多路复用。为了避免由于 TCP 的顺序传送而造成的行头阻塞,QUIC 支持连接内的多个流,以确保丢失的 UDP 数据包仅影响那些数据在该数据包中承载的流。在其他流上接收到的后续数据可以继续进行重组,并传递给应用程序。
流由流 ID 标识,流 ID 被静态分配为客户端启动的流的奇数 ID,以及服务器启动的流的偶数 ID,以避免冲突。
3.3 身份验证和加密
与 DTLS 相似,数据包编号放置在加密保护的外部,以支持对乱序接收的数据包进行解密。
3.4 丢包恢复
TCP 的重传歧义问题:TCP ACK 的接收者无法确定是为原始传输还是为传输发送了 ACK,通常会通过昂贵的超时来检测重传段的丢失。
数据包号表示一个明确的时间顺序,与 TCP 中的数据包相比,它可以更简单,更准确地进行丢失检测。QUIC 确认明确编码了数据包的接收与其发送确认之间的延迟。可以实现精确的 RTT 的估计。
3.5 流量控制
当应用程序从 QUIC 的接收缓冲区缓慢读取数据时,流控制会限制接收器必须保持的缓冲区大小。缓慢消耗的流会消耗整个连接的接收缓冲区,从而阻止发送方在其他流上发送数据。QUIC 通过限制单个流可以使用的缓冲区,改善了流中这种潜在的行头阻塞。
因此,QUIC 采用了连接级流控制,它限制了发送方可以跨所有流在接收方使用的聚合缓冲区,而流级流控制则是限制了发送方可以在任何给定流上使用的缓冲区。类似于 HTTP/2,QUIC 采用基于信用的流控制。
我们的实现还使用了类似于常见 TCP 实现的流控制窗口自动调整。
3.6 拥塞控制
QUIC 协议不依赖于特定的拥塞控制算法,并且我们的实现具有允许实验的可插入接口。
在我们的部署中,TCP 和 QUIC 都使用 Cubic 作为拥塞控制器。
正交拆解:QUIC 和拥塞控制。
3.7 NAT 重绑定和连接迁移
- NAT 超时和重新绑定:QUIC 端点只是消除了 NAT 问题,通过使用连接 ID 进行重新绑定以标识连接。
- 客户端将网络连接更改为新的IP地址:客户端启动的连接迁移是一项正在进行的工作,目前部署有限。
3.8 HTTPS 的 QUIC 发现
客户端不知道给定的服务器是否支持 QUIC。
当我们的客户端第一次向源发出 HTTP 请求时,它将通过 TLS/TCP 发送该请求。我们的服务器通过在其 HTTP 响应中包含“Alt-Svc”标头来通告 QUIC 支持,此标头告诉客户端使用 QUIC 可以尝试与原始服务器建立连接。
3.9 开源实现
Chromium:源代码使用 C++,并且包含大量的单元测试和端到端测试。该实现包括一个测试服务器和一个 testclient,它们可以用于实验,但不能针对生产级性能进行调整。
四、实验框架
Chrome 和服务器机群中的 experimentation 框架,这些框架可让我们安全地进行 QUIC 实验。
- 支持 AB 测试
- 可以快速禁止实验
- 可以监控各种指标
这种机制使我们能够在全球范围内使用 QUIC 进行受控实验,同时严格限制了由这些实验引起的大规模停机的风险。我们的服务器报告与当前和历史 QUIC 连接有关的性能数据。该数据由集中监控系统收集,该系统将其汇总并提供可视化和警报。
一套完备的测试、监控和告警框架。
五、因特网规模的部署
5.1 部署之路
- 隐秘的线上测试:Chrome于2013年6月添加了QUIC支持。通过可选的命令行标志启用了QUIC,因此有效使用仅限于QUIC开发团队。
- 金丝雀发布:2014年初,我们对QUIC的稳定性充满信心,并通过Chrome的实验框架为一小部分用户(<0.025%)启用了QUIC。由于QUIC被证明是高性能和安全的,因此这一比例有所增加。
- 全量发布:截至2017年1月,几乎所有Chrome和Android YouTube应用程序的所有用户都打开了QUIC。
发现了一个 Bug:0-RTT 请求中的未加密数据,立即全量禁用 QUIC 并修复。
移动流量中的 QUIC 也在增长。
稳步迭代的前提下,上一个版本的软件总是经过充分的测试和验证的。相比之下,不能回滚的新版本软件就是空中楼阁。
5.2 监控指标:搜索时延
以 QUIC 的搜索延迟作为性能监控指标。
六、QUIC 性能
我们定义了驱动 QUIC 开发和部署的三个关键应用程序指标,并描述了 QUIC 对这些指标的影响。QUIC 用户和 TLS/TCP 用户在以下三个方面的区别指标:搜索延迟,视频播放延迟和视频缓冲率。还描述了 QUIC 在服务器上的 CPU 利用率。
6.1 实验启动
6.2 传输和应用指标
握手延迟更少。
例如,亚马逊估计延迟时间每增加100毫秒,利润就会减少1%,谷歌估计网络搜索延迟时间每增加100毫秒,每位用户的每日搜索量就会明显减少,而雅虎证明用户更有可能在点击延迟较低的结果页上执行点击。
追求极致的背后,是巨大的利润杠杆
6.3 搜索时延
大部分延迟减少来自于0-RTT握手。
6.4 视频时延
大部分延迟减少来自于0-RTT握手。
6.5 视频重缓存速率
- 丢失恢复延迟
- 连接吞吐量
6.6 地区的性能
接入网络质量和与Google服务器之间的距离差异会导致不同地理位置的RTT和重传速率发生变化。
因此 QUIC 在 TLS/TCP 方面的性能收益并不是在整个地理区域或网络质量上均匀分布的:在平均RTT较高的网络和区域中收益更大并且会有更高的网络丢失率。
6.7 服务器 CPU 利用率
QUIC 的实现最初是着眼于快速功能开发和调试的便捷性,而不是 CPU 效率。
当我们开始测量通过 QUIC 服务 YouTube 流量的成本时,我们发现 QUIC 的服务器CPU使用率比 TLS/TCP 高 3.5 倍。
QUIC 的 CPU 成本的三个主要来源是:
- 加密;
- UDP数据包的发送和接收;
- 保持内部QUIC状态。
尽管 QUIC 仍将比 TLS/TCP 更加昂贵,但仍有可能进一步降低成本。
因算力而导致的局限性会因为摩尔定律而逐渐消失,被架构设计和逻辑框架所拖累才是软件毁灭的根源。
6.8 性能局限性
- 预热连接:当应用程序通过主动执行握手来隐藏握手延迟时,这些应用程序不会从 QUIC 的 0-RTT 握手中获得任何可衡量的收益。
- 高带宽,低延迟,低损耗的网络:使用带宽充足,低延迟和低丢失率的网络,QUIC 对增益几乎没有影响,有时还会对性能造成负面影响。当在非常高的带宽(超过100 Mbps)和/或非常低的RTT连接(几毫秒)上使用时,QUIC 的性能可能不如 TCP。
- 移动设备:QUIC 为移动用户带来的收益通常比桌面用户的收益小。移动电话对 CPU 的约束更大,导致当网络带宽充足时,CPU 成为瓶颈。
TCP 是理想状态的最佳逻辑;QUIC 是对现实情况的适当妥协。
七、实验与经验
7.1 包大小的考量
我们选择1350字节作为QUIC的默认有效负载大小。
7.2 UDP 阻塞和限制
我们在检测到这种节流的整个自治系统(AS)的服务器上手动禁用QUIC,并与运行网络的运营商联系,要求他们删除或至少提高其限制。
7.3 前向错误校正
前向纠错(FEC)在发送的数据流中使用冗余,以使接收器无需显式重新传输即可恢复丢失的数据包。
7.4 用户空间部署
开发实践直接影响部署代码的健壮性。与现代软件开发实践保持一致,严重依赖大量的单元和端到端测试。
用户空间开发,用户空间应用程序不像内核那样受内存限制,不受内核的限制API,并可以与服务器基础结构中的其他系统自由交互。
7.5 中间盒实验
QUIC 设计的前提:在部署端到端变更时,加密是唯一可确保不被中间盒使用的手段。
八、相关工作
- SPDY 旨在减少Web延迟,并已被HTTP/2标准所包含。QUIC是这项工作的自然扩展,旨在进一步降低堆栈的延迟。
- QUIC的设计最接近结构化流传输(SST)。在其他相似之处中,SST使用通道标识符,使用单调递增的数据包编号,对传输头进行加密,并使用轻量级流。
- 流多路复用以避免行头阻塞它存在于SCTP,SST 中,并作为Minion 中的消息链接。
- MinimaLT 具有类似的0-RTT握手,在加密的MinimaLT“隧道”内复用应用程序“连接”,并对聚合执行拥塞控制和丢失检测。MinimaLT会在连接从一个IP地址迁移到另一个IP地址时另外防止其链接。随着QUIC在IETF上的发展,目前正在考虑保护隐私的功能。已提出对TCP和TLS的修改以解决其握手延迟。
- TCP快速开放(TFO)通过允许将TCP SYN段中的数据通过重复连接到同一服务器的方式传递给接收方来解决TCP的握手延迟。
如果某个想法是你唯一的想法,那就没有比它更危险的东西。
九、结论
QUIC是作为实验设计和启动的,现已成为我们服务基础架构的核心部分。
我们的实验基础架构对QUIC的部署-测量-修订周期至关重要,它使我们能够构建和调整适合当今Internet的协议。
我们希望继续致力于降低服务器和客户端的QUIC的CPU成本,并改善QUIC的性能,适应移动设备。