在去年的生日周,我们宣布初步支持QUIC和HTTP/3(当时称为“HTTP over QUIC”),这是web的新标准,支持更快、更可靠、更安全的到web端点(如网站和API)的连接。我们还让客户加入等待队列,从而在QUIC和HTTP/3可用后立即试用。
从那时起,我们一直通过互联网工程任务组(包括Google Chrome和Mozilla Firefox)与业界同行合作,以迭代HTTP/3和QUIC标准文档。在标准日趋成熟的同时,我们还致力于改善对网络的支持。
**我们现在很高兴地宣布,Cloudflare边缘网络已提供QUIC和HTTP/3支持。**我们很高兴谷歌Chrome和Mozilla Firefox,这两家领先的浏览器供应商和合作伙伴加入到我们的行列中来,让我们的网络更快、更可靠。
用谷歌的软件工程师Ryan Hamilton的话来说,“HTTP/3应该使每个人的网络变得更好。Chrome和Cloudflare团队紧密合作,将HTTP/3和QUIC从新兴标准引入到广泛采用的技术中,从而改善web。行业领导者之间的强大合作伙伴关系使互联网标准创新成为可能,我们期待我们的继续合作。”
如果你是一名使用我们的服务和边缘网络来让你的网络更快更安全的Cloudflare客户,(QUIC和HTTP/3支持)这对你来说意味着什么呢?这意味着,只要在Cloudflare控制面板中为您的域启用 HTTP/3支持后,您的客户就可以使用HTTP/3与您的网站和API进行交互。我们一直在有条不紊地邀请我们HTTP/3等候队列名单上的客户开启此功能(所以请注意我们的电子邮件),在未来几周,我们将使每个人都可以启用该功能。
如果你是一名互联网用户,通过浏览器和其他客户端与站点和API交互,那么这个声明又意味着什么呢?从今天开始,您可以使用Chrome Canary通过HTTP/3与Cloudflare和其他服务器进行交互。对于那些正在寻找命令行客户端的人,curl还提供了对HTTP/3的支持。本文后面的内容将介绍如何使用支持HTTP/3的Chrome和curl。
鸡和蛋的问题
互联网上的标准创新在历史上一直很困难,因为有一个“先有鸡还是先有蛋”的问题:需要先有服务器支持(如Cloudflare或其他大型响应数据来源)还是客户端支持(如浏览器、操作系统等)?连接的两端都需要支持新的通信协议,才能使其发挥作用。
Cloudflare推动Web标准发展的历史由来已久,从HTTP/2(HTTP/3之前的HTTP版本)到TLS 1.3,再到加密SNI之类的东西。我们与志同道合的组织合作,从而推动了标准的发展,这些组织与我们都希望帮助建立更好的互联网。我们推动HTTP/3成为主流的努力没有什么不同。
在整个HTTP/3标准开发过程中,我们一直与业界合作伙伴密切合作,构建并验证与我们的边缘支持兼容的客户端HTTP/3支持。我们很高兴谷歌Chrome和curl能够加入,这两款浏览器都可以通过HTTP/3向Cloudflare边缘发出请求。Mozilla Firefox则希望尽快在夜间发布的版本中提供支持。
综上所述:今天是互联网用户的好日子;HTTP/3的广泛推出将意味着所有人都能获得更快的web体验,而今天的支持是朝着这一目标迈出的一大步。
更重要的是,今天是互联网的好日子:Chrome、curl和Cloudflare,很快,Mozilla将相继推出实验性但功能强大的HTTP/3支持,这表明互联网标准的创建过程是有效的。在互联网工程任务组的协调下,行业合作伙伴、竞争对手和其他关键利益相关者可以一起制定有益于整个互联网的标准,而不仅仅是那些行业巨头。
Firefox的首席技术官Eric Rescorla总结得很好:“开发新的网络协议是很困难的,要正确地实现它就需要我们每个人的共同努力。在过去几年里,我们一直与Cloudflare和其他行业合作伙伴合作,测试TLS 1.3,现在是HTTP/3和QUIC。Cloudflare对这些协议的早期服务器端支持已帮助我们解决了客户端Firefox实施中的互操作性问题。我们期待着共同提高互联网的安全性和性能。”
我们是如何走到这一步的?
在深入探讨HTTP/3之前,让我们快速浏览一下HTTP多年来的发展,以便更好地理解为什么互联网需要HTTP/3。
这一切始于1996年HTTP/1.0规范的发布,该规范定义了我们今天所知道的基本HTTP文本连线格式(出于这篇文章的目的,我权当HTTP / 0.9不存在)。在HTTP/1.0中,客户端和服务器之间的每次请求/响应交换都会创建一个新的TCP连接,这意味着在每个请求之前TCP和TLS都要完成握手,所有请求都会产生延迟。
更糟糕的是,TCP没有在建立连接后尽快发送所有未完成的数据,而是建立了名为“慢启动”的预热时间,从而使TCP拥塞控制算法可以在网络路径发生拥塞之前的任何给定时刻确定可传输的数据量,并避免将它无法处理的数据包泛洪到网络中。但是由于新连接必须经过缓慢的启动过程,所以它们无法立即利用上所有可用的网络带宽。
几年后,HTTP规范的HTTP/1.1修订版试图通过引入“保持在线”连接的概念来解决这些问题,该概念允许客户端重用TCP连接,从而分摊建立初始连接的成本和跨多个请求的缓慢启动。但是,这并不是什么灵丹妙药:虽然多个请求可以共享同一个连接,但它们仍然必须一个接一个地序列化,因此客户端和服务器在任何给定时间都只能为每个连接执行一个请求/响应交换。
随着网络的发展,随着多年来每个网站所需资源(CSS,JavaScript,图像等)的增加,浏览器在获取和呈现网页时对并发性的需要日趋突出。但是,由于HTTP/1.1只允许客户端一次进行一次HTTP请求/响应交换,因此在网络层上获得并发的唯一方法是并行使用多个TCP连接到同一源,从而丧失了保持连接的大部分好处。虽然连接在一定程度上(但程度更小)仍然可以被重用,但我们又回到了起点。
最终,在十几年后,SPDY和HTTP/2出现了,它首次引入了HTTP“流”的概念:这是一种抽象的概念,允许HTTP实现在同一个TCP连接上并发地复用不同的HTTP交换,允许浏览器更有效地重用TCP连接。
但是,这并不是什么灵丹妙药!HTTP/2只解决了最初的问题——对单个TCP连接的使用低效——因为现在可以在同一连接上同时传输多个请求/响应。然而,所有的请求和响应都会受到包丢失的影响(例如,由于网络拥塞),即使丢失的数据只涉及单个请求。这是因为虽然HTTP/2层可以在单独的流上隔离不同的HTTP交换,但是TCP不了解这种抽象,它看到的只是一个没有特定含义的字节流。
TCP的作用是将整个字节流按正确的顺序从一个端点传递到另一个端点。当一个携带这些字节的TCP包在网络路径上丢失时,它会在流中产生一个缺口,当检测到丢失时,TCP需要重新发送受影响的包来填补这个缺口。这样做时,在丢失的字节之后成功交付的字节无一可被交付给应用程序,即使它们本身没有丢失,并且属于完全独立的HTTP请求。因此,它们最终会带来不必要的延迟,因为TCP无法知道应用程序是否能够在不丢失比特的情况下处理它们。这个问题被称为“前端阻塞”。
走进HTTP/3
这就是HTTP/3的用武之处:它不使用TCP作为会话的传输层,而是使用QUIC(一种新的Internet传输协议),该协议将流作为传输层的一级公民引入。QUIC流共享相同的QUIC连接,因此不需要额外的握手和慢启动来创建新的QUIC流,但QUIC流是独立交付的,因此在大多数情况下,包丢失只影响一个流而不影响其他流。这是可能的,因为QUIC数据包被封装在UDP数据报头的顶部。
与TCP相比,使用UDP可以提供更大的灵活性,并且可以使QUIC完全于用户空间中实现——对协议实现的更新不像TCP那样需要绑定到操作系统更新。使用QUIC,可以简单地将HTTP级别的流映射到QUIC流的顶部,从而获得HTTP/2的所有好处,而不会产生前端阻塞。
QUIC还结合了典型的3次TCP握手和TLS 1.3的握手。结合了这些步骤意味着QUIC在默认情况下提供了加密和身份验证,并且可以更快地建立连接。换句话说,即使HTTP会话中的初始请求需要一个新的QUIC连接,在数据开始流动之前产生的延迟也低于使用TLS的TCP时的情况。
但是,何不直接在QUIC上使用HTTP/2,而非创建一个全新的HTTP修订。毕竟,HTTP/2还提供了流多路复用特性。事实证明,情况要复杂得多。
虽然一些HTTP/2特性可以很容易地映射到QUIC上,但并不是所有特性都这样。特别是HTTP/2的请求头压缩方案HPACK,它在很大程度上取决于将不同的HTTP请求和响应发送到端点的顺序。QUIC在单个流中强制字节的传递顺序,但不保证不同流之间的顺序。
这种行为需要创建一个新的HTTP请求头压缩方案,称为QPACK,它修复了这个问题,但是需要更改HTTP映射。此外,QUIC本身已经提供了HTTP/2提供的某些功能(例如每流流控制),因此我们从HTTP/3中删除了这些功能,以消除协议中不必要的复杂性。
HTTP/3,由美味的蛋饼驱动
QUIC和HTTP/3是非常令人兴奋的标准,有望解决以前标准的许多缺点,并开创网络性能的新纪元。那么,我们如何从令人兴奋的标准文档过渡到可行实现呢?
Cloudflare的QUIC和HTTP/3的支持是由quiche(我们自己用Rust编写的开源实现)提供的。
您可以在GitHub上找到它,网址为github.com/cloudflare/quiche。
我们在几个月前发布了quiche,从那以后,在现有的QUIC支持的基础上,我们又增加了对HTTP/3协议的支持。我们设计quiche的方式使它可以用于HTTP/3客户端和服务器实现,或者仅用于普通的QUIC客户端和服务器。
如何为我的域启用HTTP/3?
如前所述,我们已经开始为注册等候名单的客户提供服务。如果您在等候名单上,并且已经收到我们的来信,通知您现在可以为您的网站启用该功能,则只需转到Cloudflare控制面板,然后手动从“网络”选项卡切换此开关:
我们希望在不久的将来,所有的客户都能使用HTTP/3特性。
启用后,您可以通过多种方式体验HTTP/3:
使用Google 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”选项卡显示的内容:
请注意,由于Chrome中HTTP/3支持的实验性质,该协议在开发者工具中实际上被标识为“http2+quic/99”,但不要被这个欺骗了,它确实是HTTP/3。
使用curl
curl命令行工具也支持HTTP/3作为一个实验特性。您需要从git下载最新的版本,并按照有关如何启用HTTP / 3支持的说明进行操作。
如果您运行的是macOS,我们还可以通过Homebrew轻松安装支持HTTP/3的curl版本:
为了执行HTTP / 3请求,您需要在常规curl命令中添加“--http3”命令行标志:
% brew install --HEAD -s https://raw.githubusercontent.com/cloudflare/homebrew-cloudflare/master/curl.rb
使用quiche的http3-客户端
% ./curl -I https://blog.cloudflare.com/ --http3
HTTP/3 200
date: Tue, 17 Sep 2019 12:27:07 GMT
content-type: text/html; charset=utf-8
set-cookie: __cfduid=d3fc7b95edd40bc69c7d894d296564df31568723227; expires=Wed, 16-Sep-20 12:27:07 GMT; path=/; domain=.blog.cloudflare.com; HttpOnly; Secure
x-powered-by: Express
cache-control: public, max-age=60
vary: Accept-Encoding
cf-cache-status: HIT
age: 57
expires: Tue, 17 Sep 2019 12:28:07 GMT
alt-svc: h3-23=":443"; ma=86400
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 517b128df871bfe3-MAN
最后,我们还提供了一个基于quiche的HTTP / 3命令行客户端示例(以及命令行服务器),您可以使用该客户端来试用HTTP/3。
要运行它,首先需要克隆quiche的GitHub库:
然后构建它。您需要一个可运行的Rust和Cargo安装程序才能工作(我们建议使用rustup轻松设置一个有效的Rust开发环境)。
$ git clone --recursive https://github.com/cloudflare/quiche
最后,您可以执行一个HTTP/3请求:
$ cargo build --examples
下一步是什么?
$ RUST_LOG=info target/debug/examples/http3-client https://blog.cloudflare.com/
在接下来的几个月里,我们将致力于改进和优化我们的QUIC和HTTP/3实现,最终将允许每个人启用这个新功能,而不必在等待列表中排队。随着标准的发展,我们将继续更新我们的实现,标准草案版本之间可能会产生中断性的变更。
以下是我们计划路线图上的一些新特性,我们对此特别兴奋:
连接迁移
QUIC支持的一个重要特性是在不同网络之间无缝透明的连接迁移(比如从您早晨上班时家里的WiFi网络切换到运营商的移动网络),而不需要创建一个全新的连接。
此功能将需要对我们的基础架构进行一些其他更改,但是我们很高兴将来能为我们的客户提供这些功能。
零往返时间恢复
与TLS 1.3一样,QUIC支持一种操作模式,允许客户端在连接握手完成之前就开始发送HTTP请求。我们还没有在我们的QUIC部署中支持这个特性,但是我们将努力使它可用,就像我们已经为TLS 1.3支持所做的那样。
HTTP/3:现已上线!
我们很高兴能支持HTTP/3,并且在致力于标准化QUIC和HTTP/3的同时允许我们的客户进行实验。我们将继续与其他组织合作,包括谷歌和Mozilla,以最终确定QUIC和HTTP/3标准,并鼓励大家广泛采用。
这就是为所有人提供的更快,更可靠,更安全的Web体验。