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
。一直一来,UDP
在 IP
协议的家族中存在感就非常低。我们甚至在谈论相关协议时,经常会说 TCP/IP
协议咋样咋样,似乎默认了 UDP
协议就是一个简陋的过时协议,而且应用场景有限。
首先回顾下 UDP
协议的基本概念:UDP
协议面向报文,它是无连接的,将数据分成小的数据包(通常为固定的 64KB)进行传输。
UDP
报文信息简单,不保证可靠交付,允许出现数据包丢失或者乱序的情况。
这就意味着,只要数据大于一个 UDP
包,就得拆开发送。拆开后,数据的顺序、可靠性都不保证。这也是 HTTP
没办法直接使用 UDP
的根本原因。
TCP 做(错)了什么
既然 UDP
能力如此不健全,与 HTTP
相依相伴 25 年的 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 上的每个页面加载打开多个并行 TCP 连接(通常每个域名会单独分配 6 个连接,但同时加载的资源超出这个数目时,还是会阻塞)
HTTP2 的解决方案
HTTP2 为解决这个问题,增加了多路复用特性。为每个数据包添加了数据帧(DATA Frame),描述一个数据块的尺寸、编号,相当于为每个数据帧划定了边界,允许复用单个 TCP 连接,并行下载资源。
TCP 队头阻塞
现在 HTTP 协议自己的队头阻塞问题完美解决了,但 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
TLS 还支持 0-RTT 数据传输,即复用连接时无需握手。这可以在一定程度上减少延迟,但也可能增加安全风险(这意味着客户端可以在没有任何验证的情况下向服务器发送数据)。
QUIC 采用 TLS1.3,极大缩短了 TLS 握手的时间。QUIC 将加密和传输握手结合在一起,减少了建立一条安全连接所需的往返。
此外 TLS1.3 对密钥协商、身份认证方式均有优化(详见参考)
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
参考
- 震惊!HTTP/3 竟然抛弃了 TCP
- 震惊!HTTP/3 化解了队头阻塞的难题,竟然栽在了这里:原文 - 译文
- 震惊!QUIC 竟然重新造了个轮子
- 震惊!终于等到中文版 QUIC 协议文档
- 震惊!原来 TLS1.3 长这样