QUIC

QUIC是一种通用传输层协议，最初由谷歌工程师Jim Roskind提出。该协议于2012年实现并部署，2013年随着实验范围的扩大而公开发布。同时相关人士在IETF会议上就该协议进行说明。虽然其长期处于互联网草案阶段，但从Chrome浏览器至谷歌服务器的连接中，超过一半的连接都使用了QUIC。Microsoft Edge、Firefox都已支持此协议。QUIC于RFC9000中被正式标准化。

QUIC协议名称最初来源于“快速UDP互联网连接”（Quick UDP Internet Connection）的首字母缩写，但在IETF标准中，QUIC不是任何内容的缩写，而是协议名称本身。QUIC提高了目前使用TCP的面向连接的网络应用的性能。QUIC基于UDP实现可靠传输，在单个连接中支持多个独立的数据流，并试图在互联网传输的部分应用场景中替代TCP。

QUIC与HTTP/2的多路复用连接协同工作，允许多个数据流独立到达所有端点，因此不受涉及其他数据流的丢包影响。HTTP/2虽然支持多路复用，但HTTP/2底层仍依赖TCP，而TCP必须保证字节流按序交付，当TCP连接中的某个数据包丢失时，会导致所有HTTP/2数据流受到队头阻塞的影响。

QUIC的次要目标包括降低连接和传输时延，以及每个方向的带宽估计以避免拥塞。此外，该协议还可以扩展前向纠错（FEC），以进一步提高预期错误时的性能，这被视为协议演进的下一步。

2015年6月，QUIC规范的互联网草案提交给IETF进行标准化。2016年，成立了QUIC工作组。2018年10月，IETF的HTTP工作组和QUIC工作组共同决定将QUIC上的HTTP映射称为 "HTTP/3"，以提前使其成为全球标准。2021年5月IETF公布RFC9000，QUIC规范推出了标准化版本。

## 背景

传输控制协议 (TCP) 旨在为两个端点之间发送数据流提供一个接口。数据交给TCP系统，TCP系统确保数据以完全相同的形式传到另一端，否则连接将提示存在错误。

为此，TCP将数据分解成网络封包，并在每个数据包中添加少量数据。这些附加数据包括一个序列号，用于检测丢失或到达顺序不正确的数据包，以及一个校验和，可以检测数据包数据内的错误。当其中任何一个问题发生时，TCP使用自动重传请求（ARQ）告诉发送方重新发送丢失或损坏的数据包。

在大多数实现中，TCP会将连接上的任何错误视为阻塞，停止进一步传输，直到错误得到解决或连接被视为失败。如果使用单个连接来发送多个数据流，就像在HTTP/2协议中那样，所有这些数据流都会被阻止，尽管其中只有一个可能有问题。例如，如果在下载用于收藏夹图标的GIF图像时出现一个错误，页面的其余部分将等待问题得到解决。

由于TCP系统被设计成类似“数据管道”或流，TCP刻意被设计成并不知晓其传输的数据之细节。如果对传输的数据存在额外需求，如需要使用TLS加密，那么此类协议必须建立在TCP的上层。每种协议都需要自己的握手过程，结果会导致在建立连接前需要大量交换数据，加之长距离通信的固有延迟，从而给整个传输过程增加大量开销。

## 介绍

<image>

QUIC旨在提供几乎等同于TCP连接的可靠性，但延迟大大减少。它主要通过两个理解HTTP流量的行为来实现这一点。

第一个变化是在连接建立期间大大减少开销。由于大多数HTTP连接都需要TLS，因此QUIC使协商密钥和支持的协议成为初始握手过程的一部分。

当客户端打开连接时，服务器响应的数据包包括将来的数据包加密所需的数据。这消除了TCP上的先连接并通过附加数据包协商安全协议的需要。其他协议可以以相同的方式进行服务，并将多个步骤组合到一个请求中。

然后，这些数据既可用于初始设置中的后续请求，也可用于未来的请求。

QUIC使用UDP协议作为其基础。UDP不包含丢包恢复机制，相反，每个QUIC流是单独控制的，并且在QUIC级别而不是UDP级别重传丢失的数据。这意味着如果在某个流中发生丢包或重传，协议栈仍然可以独立地继续为其他流提供服务。

这在提高易出错链路的性能方面非常有用，因为在大多数情况下TCP协议通知数据包丢失或损坏之前可能会收到大量的正常数据，但是在纠正错误之前其他的正常请求都会等待甚至重发。

QUIC在修复单个流时可以自由处理其他数据，也就是说即使一个请求发生了错误也不会影响到其他的请求。

QUIC包括许多其他更普通的更改，这些更改也可以优化整体延迟和吞吐量。例如，每个数据包是单独加密的，因此加密数据时不需要等待部分数据包。

在TCP下通常不可能这样做，其中加密记录在字节流中，并且协议栈不知道该流中的更高层边界。这些可以由运行在更上层的协议进行协商，但QUIC旨在通过单个握手过程完成这些。

QUIC的另一个目标是提高网络切换期间的性能，例如当移动设备的用户从WiFi热点切换到移动网络时发生的情况。

当这种情况发生在 TCP 连接上时，会经历一个较为漫长的过程：已有连接会因为无法继续通信而逐渐超时，并在需要时重新建立。

为解决此问题，QUIC包含一个连接标识符，该标识符唯一地标识客户端与服务器之间的连接，而无论源IP地址是什么。这样只需发送一个包含此ID的数据包即可重新建立连接，因为即使用户的IP地址发生变化，原始连接ID仍然有效。

QUIC在应用程序空间中实现，而不是在操作系统内核中实现。当数据在应用程序之间移动时，这通常会由于上下文切换而调用额外的开销。

但是在QUIC下协议栈旨在由单个应用程序使用，每个应用程序使用QUIC在UDP上托管自己的连接。最终差异可能非常小，因为整个HTTP/2堆栈的大部分已经存在于应用程序（或更常见的库）中。

将剩余部分放在这些库中，基本上是纠错，对HTTP/2堆栈的大小或整体复杂性几乎没有影响。

QUIC允许更容易地进行未来更改，因为它不需要更改内核就可以进行更新。

QUIC的长期目标之一是添加前向纠错和改进的拥塞控制。

关于从TCP迁移到UDP的一个问题是TCP被广泛采用，并且互联网基础设施中的许多中间设备被调整为UDP速率限制甚至阻止UDP。

Google进行了一些探索性实验来描述这一点，发现只有少数连接存在此问题。所以Chromium的网络堆栈同时打开QUIC和传统TCP连接，并在QUIC连接失败时以零延迟回退到TCP连接。

### gQUIC与iQUIC

Google 最初开发的 QUIC（通常称为 gQUIC）于约 2012 年开始部署，随后提交至 IETF 进行标准化。然而，IETF 标准化后的 QUIC 与 Google 的早期实现存在显著差异。Google 的 gQUIC 最初是一种面向 Web 的通用协议，主要用于 Chromium 中 HTTP 和 HTTPS 的传输，并采用其自有的加密和传输机制。相比之下，IETF 在 gQUIC 的基础上重新设计了 QUIC，将其发展为一种通用传输层协议，采用标准 TLS 1.3 完成加密握手，并使用模块化的数据包和连接设计，以实现更好的互操作性。Chromium 随后持续跟进 IETF QUIC 的标准化进程，并逐步迁移到符合 IETF 标准的实现。

## 流量控制

与大多数传输协议一样，QUIC 具有流量控制以保护接收端免受缓冲区overflow的影响。QUIC 是基于 UDP 传输，而 UDP 没有流量控制，因此 QUIC 实现了自己的流量控制机制。与TCP不同，QUIC并不是通过ACK确认当前收到的数据编号，而是通过 control frame 实现类似HTTP/2的基于信用的流量控制机制。

## 实现

### 客户端

Google Chrome于2012年开始开发QUIC协议并且于Chromium版本 29（2013年8月20日释出）发布。QUIC协议在当前Chrome版本中被默认开启，活跃的会话列表在`''chrome://net-internals/#quic''`中可见。

### 服务端

截至2017年，有三种活跃维护中的实现。谷歌的服务器及谷歌发布的 原型服务器 使用Go语言编写的 quic-go 及Caddy的试验性QUIC支持。在2017年7月11日，LiteSpeed科技正式在他们的负载均衡（WebADC）及 LiteSpeed 服务器中支持QUIC。截止 17 年 12 月， 97.5%的使用 QUIC 协议的网站在 LiteSpeed 服务器中运行。

另有几种不再维护的社区产品，基于Chromium实现并且减少使用依赖的 libquic、提供libquic的Go语言绑定的 goquic、打包为Docker镜像的用来转换为普通HTTP请求的反向代理 quic-reverse-proxy。

2020年12月，支持DNS-over-QUIC协议的公共DNS解析器，由AdGuard首次公开推出服务。

## 外部链接

- Chromium: QUIC, a multiplexed stream transport over UDP
- QUIC: Design Document and Specification Rationale, Jim Roskind's original document (2012/2013)
- Daniel Stenberg: HTTP/3 explained
- Linux Weekly News: Connecting on the QUIC (2013)
- QUIC: , IETF-88 TSV Area Presentation (2013-11-07)
- Chromium Blog: Experimenting with QUIC (2013)
- QUIC: next generation multiplexed transport over UDP (Google Developers, 2014)
- HTTP over UDP: an Experimental Investigation of QUIC
- Multipath QUIC (extension to QUIC)
- Innovating Transport with QUIC: Design Approaches and Research Challenges (2017)
- Does my browser support HTTP/3 & QUIC? - Cloudflare

## 基本资料

- 开发者：IETF, Google
- 日期：2012年10月12日
- 原型：IP, UDP
- osilayer：传输层