HTTP 协议为 Web 的发展提供了驱动力,它始于 1991 年的 HTTP/0.9,在 1999 年演变为 HTTP/1.1,并由 IETF(互联网工程任务组)负责进行标准化。HTTP/1.1 存在了很长一段时间,但 Web 不断变化的需求要求推出更好的协议,于是 HTTP/2 在 2015 年出现了。去年年底,IETF 又推出新版本 HTTP/3。对于有些人来说,这是一个惊喜,但也会让他们感到有一点点困惑。想要更好地了解 HTTP/3 的前世今生,以及它接下来的规划,来自 Cloudflare 博客的这篇最新文章将为你指点迷津。

在去年的“生日周”期间,我们宣布了对新生 Web 标准 QUIC 和 HTTP/3(当时称为“ HTTP over QUIC”)的初步支持,从而可以更快、更可靠、更安全地连接到网站和 API 等 Web 端点。我们还请客户加入一个等候队列,这样 QUIC 和 HTTP/3 可用后他们就能立刻试用。

HTTP/3 的过去、现在和未来

从那以后,我们一直在通过互联网工程任务组(包括谷歌 Chrome 和 Mozilla Firefox)与业界同行合作,以迭代 HTTP/3 和 QUIC 标准文档。在标准日趋完善的同时,我们还致力改善网络的支持能力。

现在我们很高兴地宣布,Cloudflare 边缘网络已提供 QUIC 和 HTTP/3 支持。我们很高兴能与两家领先的浏览器供应商和合作伙伴谷歌 Chrome 和 Mozilla Firefox 共同合作完成这项工作,为所有人打造速度更快、更加可靠的互联网。

用谷歌高级软件工程师 Ryan Hamilton 的话来说,“HTTP/3 会改善所有人使用 Web 的体验。Chrome 和 Cloudflare 团队密切合作,将 HTTP/3 和 QUIC 从新生标准发展为广泛应用的 Web 技术改进。行业领导者之间的强大合作伙伴关系推动了互联网标准创新,我们期待双方能继续合作。”

这对 Cloudflare 的客户又意味着什么呢?你们选择我们的服务和边缘网络,是为了让 Web 更快、更安全。在 Cloudflare 仪表板为你的域启用 HTTP/3 支持后,你的客户就可以使用 HTTP/3 与你的网站和 API 交互。我们一直在邀请 HTTP/3 等候队列中的客户启用该功能,在接下来的几周内我们将向所有人开放该功能。

如果你是互联网用户,通过浏览器等客户端与网站和 API 交互,那么这份公告又意味着什么呢?从今天开始,你可以使用 Chrome Canary 通过 HTTP/3 与 Cloudflare 和其他服务器交互。如果你想用命令行客户端的人, curl 也提供了对 HTTP/3 的支持。后文将介绍如何通过 HTTP/3 使用 Chrome 和 curl。

1 母鸡和鸡蛋

互联网的标准创新一直举步维艰,这是一个先有鸡还是先有蛋的问题:是服务器先支持新标准(例如 Cloudflare 或其大型响应数据源),还是客户端先支持(例如浏览器和操作系统等)呢?连接的两端都需要支持新的通信协议才能正常工作。

Cloudflare 推动 Web 标准发展的历史由来已久,从 HTTP/2 (HTTP/3 之前的 HTTP 版本)到 TLS 1.3 ,再到加密 SNI 等等。我们与志同道合的组织合作推动标准进化,这些组织都认同我们 " 希望帮助建立更好的互联网 " 的愿望。我们将 HTTP/3 推向主流的努力也是如此。

在 HTTP/3 标准的整个开发过程中,我们一直与行业合作伙伴紧密合作,以建立和验证与我们的边缘支持兼容的 HTTP/3 客户端支持。我们很高兴能与谷歌 Chrome 和 curl 合作,今天它们都可以通过 HTTP/3 向 Cloudflare edge 发出请求。Mozilla Firefox 预计也将为 nightly 版本提供支持。

总而言之,今天对于互联网用户来说是美好的一天。HTTP/3 的广泛普及将为所有人带来更快的 Web 体验,而今天的支持工作是朝着这一方向迈出的一大步。

更重要的是,今天也是互联网的好日子:Chrome、curl 和 Cloudflare,以及不久之后的 Mozilla 迅速推出了实验性但实用化的 HTTP/3 支持,表明互联网标准创建已经走入正轨。在互联网工程任务组的协调下,行业合作伙伴、竞争对手和其他主要利益相关者可以齐心协力制定让整个互联网,而不仅是少数巨头受益的标准。

Firefox 的 CTO Eric Rescorla 给出了很好的总结:“开发新的网络协议很困难,要使其走入正轨则需要每个人的共同努力。在过去的几年中,我们一直与 Cloudflare 和其他行业合作伙伴一起测试 TLS 1.3 到现在的 HTTP/3 和 QUIC。Cloudflare 对这些协议的服务端早期支持已帮助我们解决了客户端 Firefox 实现中的互操作性问题。我们期待这些合作能共同提高互联网的安全性和性能。”

HTTP/3 的过去、现在和未来

2 发展历史

在深入探究 HTTP/3 之前,我们先来快速浏览一下 HTTP 多年来的发展,从而更好地理解为什么互联网需要 HTTP/3。

这一切始于 1996 年 HTTP/1.0 规范的发布,该规范定义了我们今天熟知的基本 HTTP 文本连线格式(为了方便论述,我假装 HTTP/0.9 不存在)。在 HTTP/1.0 中,客户端和服务器之间交换的每个请求 / 响应都会创建一个新的 TCP 连接,这意味着所有 TCP/TLS 握手均在每个请求之前完成,因此所有请求都会产生延迟。

HTTP/3 的过去、现在和未来

更糟糕的是,TCP 不是在建立连接后尽快发送所有未完成的数据,而需要“慢启动”的预热时间,这使 TCP 拥塞控制算法能够随时确定可以传输的数据量,防止网络路径发生拥塞,并避免将无法处理的数据包都堆到网络中。但是,由于新连接必须经过缓慢的启动过程,因此它们无法立即使用所有可用的网络带宽。

几年后,HTTP 规范的 HTTP/1.1 修订版试图引入“保持活动”连接的概念来解决这些问题,它允许客户端复用 TCP 连接,从而分摊了建立初始连接和针对多个请求缓慢启动的成本。但这不是灵丹妙药,尽管多个请求可以共享同一个连接,但它们仍需逐个序列化它们,因此任意时点上客户端和服务器只能为每个连接执行一次请求 / 响应交换。

随着网络的发展,多年来网站所需资源(CSS、JavaScript 和图像等)不断增长,浏览器在获取和呈现网页时需要越来越多的并发性。但由于 HTTP/1.1 只允许客户端同时进行一次 HTTP 请求 / 响应交换,因此在网络层上获得并发能力的唯一方法是并行使用多个 TCP 连接到同一来源,代价就是牺牲了活动连接的大多数好处。尽管连接仍会在一定程度上(但程度不大)被复用,但我们又回到了起点。

十多年过去了,SPDY 和 HTTP/2 终于相继诞生;后者率先引入了 HTTP“流”的概念:这是一种抽象概念,允许 HTTP 实现将不同的 HTTP 交换并发地复用到同一 TCP 连接上, 使浏览器更高效地复用 TCP 连接。

HTTP/3 的过去、现在和未来

但这也不是灵丹妙药!HTTP/2 解决了最初的问题——单个 TCP 连接的使用效率低——因为现在可以通过同一连接同时传输多个请求 / 响应。但是,即使只有单个请求丢失数据,所有请求和响应也会同样受到数据包丢失(比如因为网络拥塞)的影响。这是因为尽管 HTTP/2 层可以在不同的流上隔离不同的 HTTP 交换,但是 TCP 不了解这种抽象,并且后者所看到的只是字节流,没有特殊含义。

TCP 的作用是以正确的顺序从一个端点到另一端点传递整个字节流。当承载某些字节的 TCP 数据包在网络路径上丢失时将在流中造成间隙,并且 TCP 需要在检测到丢失时重新发送受影响的数据包来弥补这一间隙。这样做时,即使丢失数据之后的数据属于完全不同的 HTTP 请求,自己也根本没有丢失,也能正常传递成功,它们还是不能正常传递给应用程序。因此它们只能毫无必要地产生延迟,因为 TCP 无法知道应用程序缺少了丢失的数据包时能否处理后面的数据。这个问题称为“行首阻塞”。

3 了解 HTTP/3

这就是 HTTP/3 的用武之地:它不是使用 TCP 作为会话的传输层,而是使用 QUIC (一种新的互联网传输协议)。该协议率先在传输层将流作为一等公民引入。多个 QUIC 流共享相同的 QUIC 连接,因此不需要额外的握手和慢启动来创建新的 QUIC 流。但 QUIC 流是独立交付的,因此在大多数情况下,只影响一个流的丢包不会影响其他流。这是因为 QUIC 数据包封装在 UDP 数据报的顶部。

与 TCP 相比,使用 UDP 可以提供更大的灵活性,并且可以使 QUIC 实现完全存在于用户空间中——协议实现的更新不像 TCP 那样依赖操作系统的更新。借助 QUIC,可以将 HTTP 级别的流简单地映射到 QUIC 流的顶部,从而在享受 HTTP/2 所有好处的同时避免了行首阻塞。

QUIC 还结合了典型的 3 向 TCP 握手和 TLS 1.3 的握手。结合这些步骤意味着加密和身份验证能够默认提供,并且还可以更快地建立连接。换句话说,即使 HTTP 会话中的初始请求需要新的 QUIC 连接,在数据开始流动之前的等候延迟也比使用 TLS 的 TCP 要低。

HTTP/3 的过去、现在和未来

但为什么不在 QUIC 上使用 HTTP/2,而要创建一个全新的 HTTP 版本呢?毕竟 HTTP/2 还提供了流多路复用功能。事实证明这样做比想象的复杂许多。

确实可以轻松地将某些 HTTP/2 功能映射到 QUIC 上,但并非所有功能都能如此。特别是一种称为 HPACK 的 HTTP/2 标头压缩方案,在很大程度上取决于将不同的 HTTP 请求和响应传递到端点的顺序。QUIC 强制执行单个流中字节的传递顺序,但不保证不同流之间的顺序。

此行为需要创建一个称为 QPACK 的新 HTTP 标头压缩方案,它可以解决问题,但需要更改 HTTP 映射。另外,QUIC 本身已经提供了 HTTP/2 的某些功能(例如按流区分的流控制),因此我们从 HTTP/3 中删除了这些功能,从而消除了协议中不必要的复杂性。

4 HTTP/3,由美味的蛋饼(quiche)驱动

QUIC 和 HTTP/3 是非常令人兴奋的标准,有望解决以前标准的诸多缺点,并开创了网络性能的新纪元。那么我们是如何从令人兴奋的标准文档发展出可行的实现的呢?

Cloudflare 的 QUIC 和 HTTP/3 支持由 quiche 提供支持,这是我们自己用 Rust 编写的开源实现。

HTTP/3 的过去、现在和未来

你可以在 GitHub 上找到它

我们在几个月前发布了 quiche,此后在已有的 QUIC 支持基础上增加了对 HTTP/3 协议的支持。我们的设计使 quiche 可以用于实现 HTTP/3 客户端和服务器,或仅用于普通的 QUIC 服务器实现。

5 如何为我的域启用 HTTP/3?

如上所述,我们已经开始为注册了等候名单的客户提供服务。如果你在名单上,并且已经收到邮件通知,表示现在可以为你的网站启用该功能,则只需转到 Cloudflare 仪表板,然后手动从“Network”选项卡启用此开关:

HTTP/3 的过去、现在和未来

我们希望在不久的将来向所有客户提供 HTTP/3 功能。启用后,你可以通过多种方式尝试 HTTP/3:

使用谷歌 Chrome 作为 HTTP/3 客户端

为了使用 Chrome 浏览器通过 HTTP/3 连接到你的网站,你首先需要下载并安装最新的 Canary 版本。然后使用“–enable-quic”和“–quic-version=h3-23”命令行参数启动 Chrome Canary。

使用必需的参数启动 Chrome 后,你只需在地址栏中输入你的域,然后查看它是否已通过 HTTP/3 加载(你可以使用 Chrome 开发人员工具中的“Network”选项卡来检查所使用的协议版本)。请注意,由于浏览器和服务器之间协商 HTTP/3 的方式,HTTP/3 可能不会用于到域的前几个连接,因此你应该尝试重新加载几次页面。

如果这看起来太复杂了,但也请放心,因为随着时间的流逝,Chrome 对 HTTP/3 的支持将变得更加稳定,启用 HTTP/3 将会变得更加容易。

这是通过 HTTP/3 浏览此博客时,开发人员工具中的“Network”选项卡显示的内容:

HTTP/3 的过去、现在和未来

请注意,由于 Chrome 对 HTTP/3 支持的实验性质,该协议在开发人员工具中实际上被标识为“ http2+quic/99”,但请不要误解,它就是 HTTP/3。

使用 curl

curl 命令行工具也支持 HTTP/3 实验功能。你需要从 git 下载最新版本,并按照启用 HTTP/3 支持的说明操作。

如果你运行的是 macOS,我们还可以通过 Homebrew 轻松安装带有 HTTP/3 的 curl 版本:

 % brew install --HEAD -s https://raw.githubusercontent.com/cloudflare/homebrew-cloudflare/master/curl.rb

为了执行 HTTP/3 请求,你需要做的就是将“–http3”命令行标志添加到普通 curl 命令中:

 % ./curl -I https://blog.cloudflare.com/ --http3HTTP/3 200date: Tue, 17 Sep 2019 12:27:07 GMTcontent-type: text/html; charset=utf-8set-cookie: __cfduid=d3fc7b95edd40bc69c7d894d296564df31568723227; expires=Wed, 16-Sep-20 12:27:07 GMT; path=/; domain=.blog.cloudflare.com; HttpOnly; Securex-powered-by: Expresscache-control: public, max-age=60vary: Accept-Encodingcf-cache-status: HITage: 57expires: Tue, 17 Sep 2019 12:28:07 GMTalt-svc: h3-23=":443"; ma=86400expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"server: cloudflarecf-ray: 517b128df871bfe3-MAN
使用 quiche 的 http3-client

最后,我们还提供了一个基于 quiche 构建的 HTTP/3 命令行客户端示例(也有命令行服务器),你可以用它来试用 HTTP/3。

要运行它,请首先克隆 quiche 的 GitHub 存储库:

$ git clone --recursive https://github.com/cloudflare/quiche

然后构建它。首先你需要一个正常工作的 Rust 和 Cargo 环境(我们建议使用 rustup 轻松设置一个正常的 Rust 开发环境。

$ cargo build --examples

最后你就可以执行 HTTP/3 请求了:

$ RUST_LOG=info target/debug/examples/http3-client https://blog.cloudflare.com/
6 接下来有什么安排?

在接下来的几个月中,我们将致力于改进和优化 QUIC 和 HTTP/3 实现,最终将使所有人都可以启用这一新功能,不用再排队等候。随着标准的发展,我们也将继续更新实现,可能会在草案进化为标准之外引入重大更新。

以下是我们路线图上一些特别令人兴奋的功能:

连接迁移

QUIC 带来的一项重要功能是在不同的网络(例如你早上上班时在家中的 WiFi 网络和运营商移动网络)之间进行无缝、透明的连接迁移,而无需创建全新的连接。

HTTP/3 的过去、现在和未来

此功能需要对我们的基础架构进行一些额外更改,但是我们非常期待将来向客户提供这项改进。

零往返时间恢复

与 TLS 1.3 一样,QUIC 支持一种操作模式,允许客户端在连接握手完成之前开始发送 HTTP 请求。我们尚未在 QUIC 部署中支持此功能,但就像我们在 TLS 1.3 支持中做到的那样,我们也将努力实现此项改进。

7 HTTP/3:它面世了!

我们很高兴能够为 HTTP/3 提供支持,并让客户在 QUIC 和 HTTP/3 的标准化推进阶段进行尝试。我们将继续与其他组织(包括谷歌和 Mozilla)合作,以最终确定 QUIC 和 HTTP/3 标准并鼓励业界广泛应用。

HTTP/3 将为所有人提供更快、更可靠并更安全的 Web 体验。

原文链接:

https://blog.cloudflare.com/http3-the-past-present-and-future/

HTTP/3 的过去、现在和未来

点个在看少个 bug 👇

原文始发于微信公众号(InfoQ):HTTP/3 的过去、现在和未来

HTTP/3 的过去、现在和未来
标签: