HTTP/3.0

2022 年 6 月,HTTP3.0 协议发布为 RFC 标准1。HTTP 协议完全弃用了 TCP 协议,改用基于 UDP 的 QUIC 协议实现。

HTTP/3.0 协议的发布主要是为了解决 HTTP/2.0 协议中存在的一些问题,并提升 Web 性能和安全性。此外 HTTP/3.0 在传输层和应用层上做了根本性的变革。

UDP

说到 HTTP/3,首先要提起 UDP。一直一来,UDPIP 协议的家族中存在感就非常低。我们甚至在谈论相关协议时,经常会说 TCP/IP 协议咋样咋样,似乎默认了 UDP 协议就是一个简陋的过时协议,而且应用场景有限。

首先回顾下 UDP 协议的基本概念:UDP 协议面向报文,它是无连接的,将数据分成小的数据包(通常为固定的 64KB)进行传输。

UDP 报文信息简单,不保证可靠交付,允许出现数据包丢失或者乱序的情况。

UDP 头

这就意味着,只要数据大于一个 UDP 包,就得拆开发送。拆开后,数据的顺序、可靠性都不保证。这也是 HTTP 没办法直接使用 UDP 的根本原因。

TCP 做(错)了什么

既然 UDP 能力如此不健全,与 HTTP 相依相伴 25 年的 TCP 协议为什么会说扔就扔?TCP 到底做了什么?做错了什么?

TCP 可靠传输

TCP 可靠传输的特点,是该协议饱受青睐的主要原因。TCP 的可靠传输依赖重传机制保证

TCP 协议面向字节流,在一对一的连接中,通过字节流按顺序传输数据,对数据进行确认、重发、排序等控制提供可靠传输。

TCP 头

QUIC 协议

QUIC 是一种通用、安全、多路复用的传输层新型网络协议,它在 UDP 的基础上实现了可靠传输。此外,它强制采用 TLS 协议以保障安全性。2它的目标是取代TCP

QUIC 可靠传输

QUIC 同样采用确认重传、拥塞控制、流量控制来保证可靠传输。

QUIC 在应用层实现了 TCP 在系统内核层实现的功能,放弃了内核甚至硬件级的支持,但是也因此带来了更多的优化和改进。

队头阻塞

HTTP/1.1队头阻塞

基于 TCP 的特性,在 http1.1 中,一个连接完整传递一个资源。如果要传递多个资源,没办法复用连接,必须等待之前的连接释放。

如果往 HTTP1.1 连接中硬塞多个资源会发生什么?比如一个页面同时请求 js 文件和 css 文件的场景。因为不同的资源没有边界,多个资源的数据会混在一起,无法区分。

Http/1.1 传多个资源会发生什么

为缓解连接无法复用导致的阻塞问题,浏览器会为 HTTP/1.1 上的每个页面加载打开多个并行 TCP 连接(通常每个域名会单独分配 6 个连接,但同时加载的资源超出这个数目时,还是会阻塞)

HTTP2 的解决方案

HTTP2 为解决这个问题,增加了多路复用特性。为每个数据包添加了数据帧(DATA Frame),描述一个数据块的尺寸、编号,相当于为每个数据帧划定了边界,允许复用单个 TCP 连接,并行下载资源。

Http/2 解决队头阻塞

http2协议复用实例

TCP 队头阻塞

现在 HTTP 协议自己的队头阻塞问题完美解决了,但 TCP 协议也有队头阻塞问题。而传输层的问题是应用层无可奈何的。

TCP 协议会将数据流拆成多个包顺序发送,如果遇到丢包,TCP 会尝试进行重传,而等待重传造成的阻塞。

TCP 被设计为数据必须保证数据的有序性,这是造成阻塞的关键。例如在采快速重传(与超时重传对应)策略时,TCP 请求的交互情况如下

TCP 队头阻塞的示意图

在 HTTP/2 的情况下,TCP 队头阻塞甚至会造成服用这个连接的多个 HTTP 请求受到影响。也就是说,在丢包率高的环境中,HTTP/2 的性能甚至不如 HTTP/1.1。

QUIC 的多路复用

QUIC 吸收 HTTP/2 的优点,外加打通传输层的优势,从根本上消除了队头阻塞。

QUIC 采用与 HTTP/2 类似的策略,允许一个连接上传输多个流。但 QUIC 协议中,允许每个流的数据包各自 ACK 和流控3。因此,即使个别流的数据包丢失,也只会影响该数据流,不会影响在这个连接上的其他数据流。

更快的握手

QUIC 严格使用 TLS4,QUIC 握手则基于 TLS 的握手过程,将加密和身份验证整合到连接建立的过程中,从而减少了握手时间和延迟。与TCP握手需要三个往返时间(RTT)相比,QUIC握手只需要一个RTT,从而加速了连接建立的过程。

TLS1.3 & TLS 1.2

TLS1.3对握手进行了哪些优化

TLS 还支持 0-RTT 数据传输,即复用连接时无需握手。这可以在一定程度上减少延迟,但也可能增加安全风险(这意味着客户端可以在没有任何验证的情况下向服务器发送数据)。

QUIC 采用 TLS1.3,极大缩短了 TLS 握手的时间。QUIC 将加密和传输握手结合在一起,减少了建立一条安全连接所需的往返。

此外 TLS1.3 对密钥协商、身份认证方式均有优化(详见参考)

直观动图看 QUIC 中的优化

QUIC 其他优化点3

单调递增的包序列号,这使得 RTT 的计算更加精准

更大的 ACK 范围,在高丢包的环境中,可以加快网络恢复,且可以在不依赖超时重传机制下继续。

将拥塞窗口从一个数据包提升为两个数据包,这将缓解因丢包而触发的超时重传所带来的延迟。虽然这会增大网络负载,但在持续拥塞的环境下,发送速率会指数级降低,因此是安全的。

QUIC 协议采用了 QPack 头部压缩算法,通过动态表和索引的方式减少请求和相应头部大小(一种 Huffman 编码的应用与优化)

HTTP/3.0 的应用现状和应用前景

QUIC 协议目前还处于不稳定的发展阶段,目前还没有稳定的 HTTP/3 服务器和客户端实现,尚未广泛应用于生产环境中。

但目前,一些大型互联网企业和网站已经开始尝试使用 HTTP/3,主流浏览器:Chrome,Firefox,Edge 也都已经支持 Http/3.0(实验功能)。

关于如何在自己的网站上启用 HTTP/3.0 以及测评,可以参考我另一篇文章,Nginx 中启用 HTTP/3.0

参考