跳到主要内容

HTTP/3 来了

HTTP 作为互联网时代以来最广为人知的一个协议,伴随着互联网的诞生、发展与繁荣,至今已经走过了30年的历史。在它的第3个大版本即将诞生之际,我们来回顾一下它的发展历史,并了解它未来的发展方向。

年份版本重要特性
1991HTTP/0.9只有 GET 方法,没有 headers,只能传输 HTML
1996HTTP/1.0引入状态码和 headers ,具备了扩展性
1997HTTP/1.1默认长连接 (Keep-Alive)
缓存控制 (cache control)
2015HTTP/2多路复用 (multiplexing)
头部压缩
2020 (draft)HTTP/3基于UDP

进化过程

HTTP 协议依赖于 TCP 连接,而 TCP 连接的创建需要“三次握手”,这是十分耗时的。HTTP/1.0 的默认机制是为每一个 HTTP 请求/响应对 单独创建 TCP 连接,因为当时的网页没有那么复杂,可能只有1个 HTML 文件。后来,网页上开始有了更多的外部资源,比如 CSS/JS/图片等等,它们可能都来自同一个服务器,让它们复用同一个 TCP 连接显然是更高效的办法,于是在 HTTP/1.1 中默认机制就改为了长连接,方便复用。

但是,当多个 请求/响应对 复用一个连接时,它们是需要排队的,只有当前面的一个 请求/响应对 传输完成了之后,下一个 请求/响应对 才能开始传输 。在页面越来越复杂,页面上的外部资源文件越来越多的情况下,这样的方式显然不够理想。更要命的是如果有队伍中有一个 请求/响应对 传输速度很慢,就会阻塞后面所有的 请求/响应对,这就是所谓的“队首阻塞” (Head-of-Line Blocking)。为了缓解这个问题,就有了一些开源节流的曲线救国方案。

为了一劳永逸地解决上述问题,显然的思路就是让一个连接能够同时传输多个 请求/响应对 。这就是 HTTP/2 的多路复用 (multiplexing),每个 请求/响应对 不再以整体为单位传输,而是被分割为独立的帧,来自不同的 请求/响应对 的帧可以互相交错发送,在接收端被重新组装复原。

HTTP 进化到这里,基本上已经“榨干”了 TCP 的最后一滴油,将 TCP 充分利用了。虽然 HTTP/2 解决了自身(应用层)的“队首阻塞”问题,但是, TCP 本身(传输层)也存在“队首阻塞”问题。这是由 TCP 的特性所决定的,它是一个可靠的、有序的协议,如果传输中一个数据包丢失了,那么整个连接都会中断来等待那个丢失的数据包进行重传。这也就意味着,尽管上层 HTTP 协议多路复用了,但是在下层 TCP 连接中依然只有一路,一旦发生丢包,就会影响后续所有的数据的传输。

既然 TCP 这条路已经走到头了,自然有人想到了传输层中与 TCP 正好互补的“兄弟” UDP 。这也就是目前正在起草的 HTTP/3 了,它基于UDP,并且使用新开发的 QUIC 协议实现了之前 HTTP/2 和 TCP 中的那些需要保留的特性。图示如下(图片来自 HTTP/3 explained ):

HTTP/3 over QUIC stack overview
HTTP/3 over QUIC stack overview

资料汇总

FAQ

怎样尽快体验 HTTP/3 ?

Cloudflare 已全面支持 HTTP/3 ,开启 CDN 即可体验。

HTTP/3 服务器如何兼容之前的版本?

原理与之前版本的协议协商机制相同。

例如,服务端如果在 UDP 端口 50781 提供 HTTP/3 服务,可以在 HTTP 响应的头部添加Alt-Svc: h3=":50781"字段通知客户端。

参考