HTTP / 1.1与HTTP / 2:有什么区别?

阅读本文后,您将了解HTTP / 1.1和HTTP / 2之间的主要区别,重点关注HTTP / 2中采用的技术更改。从1997年发布的HTTP / 1.1到最近,该协议的修订很少。但在2015年,一个名为HTTP / 2的重新构想版本开始使用,它提供了几种减少延迟的方法,特别是在处理移动平台和服务器密集型图形和视频时。

作者选择了女性工程师协会作为Write for DOnations计划的一部分接受捐赠。

介绍

超文本传输​​协议(HTTP)是一种应用程序协议,自1989年发明以来,它一直是万维网上通信的事实标准。从1997年发布的HTTP / 1.1到最近,很少有修订版本。协议。 但在2015年,一个名为HTTP / 2的重新构想版本开始使用,它提供了几种减少延迟的方法,特别是在处理移动平台和服务器密集型图形和视频时。 从那以后,HTTP / 2越来越受欢迎,一些估计表明世界上大约三分之一的网站都支持它。 在这种不断变化的环境中,Web开发人员可以从理解HTTP / 1.1和HTTP / 2之间的技术差异中受益,从而使他们能够就不断发展的最佳实践做出明智而有效的决策。

阅读本文后,您将了解HTTP / 1.1和HTTP / 2之间的主要区别,重点关注HTTP / 2为实现更高效的Web协议而采用的技术更改。

背景

为了将HTTP / 2对HTTP / 1.1所做的具体更改进行上下文化,让我们首先高级地看一下每个的历史发展和基本工作。

HTTP / 1.1

由Timothy Berners-Lee于1989年开发,作为万维网的通信标准,HTTP是一种顶级应用程序协议,可在客户端计算机与本地或远程Web服务器之间交换信息。 在此过程中,客户端通过调用GETPOST方法向服务器发送基于文本的请求。 作为响应,服务器将类似HTML页面的资源发送回客户端。

例如,假设您正在访问www.example.com域名的网站。 导航到此URL时,计算机上的Web浏览器会以基于文本的消息的形式发送HTTP请求,类似于此处显示的消息:

GET /index.html HTTP/1.1
Host: www.example.com

此请求使用GET方法,该方法请求Host:之后列出的主机服务器的数据。 作为对此请求的响应,除了HTML中要求的任何图像,样式表或其他资源之外, example.com Web服务器还向请求客户端返回HTML页面。 请注意,在第一次调用数据时,并非所有资源都返回给客户端。 请求和响应将在服务器和客户端之间来回传递,直到Web浏览器收到在屏幕上呈现HTML页面内容所需的所有资源。

您可以将这种请求和响应交换视为互联网协议栈的单个应用层 ,位于传输层 (通常使用传输控制协议或TCP)和网络层 (使用Internet协议或IP)之上):

互联网协议栈

关于此的较低级别有很多讨论,但为了获得对HTTP / 2的高级理解,您只需要知道这个抽象层模型以及HTTP所在的位置。

通过HTTP / 1.1的基本概述,我们现在可以继续重述HTTP / 2的早期开发。

HTTP / 2

HTTP / 2最初是作为SPDY协议开始的,主要在Google开发,旨在通过使用压缩,多路复用和优先级等技术来减少网页加载延迟。 IETF(Internet工程任务组)的超文本传输​​协议工作组httpbis将标准放在一起时,该协议充当HTTP / 2的模板,最终于2015年5月发布了HTTP / 2.从一开始,许多浏览器支持此标准化工作,包括Chrome,Opera,Internet Explorer和Safari。 部分由于此浏览器支持,自2015年以来该协议的采用率一直很高,新网站的费率尤其高。

从技术角度来看,区分HTTP / 1.1和HTTP / 2的最重要特征之一是二进制成帧层,它可以被认为是互联网协议栈中应用层的一部分。 与HTTP / 1.1相反,HTTP / 1.1以纯文本格式保存所有请求和响应,HTTP / 2使用二进制成帧层以二进制格式封装所有消息,同时仍保持HTTP语义,如动词,方法和标头。 应用程序级API仍将以传统的HTTP格式创建消息,但底层将把这些消息转换为二进制。 这可确保在与新协议交互时,在HTTP / 2之前创建的Web应用程序可以继续正常运行。

将消息转换为二进制允许HTTP / 2尝试新的HTTP / 1.1数据传递方法,这种对比是两种协议之间实际差异的根源。 下一节将介绍HTTP / 1.1的交付模型,然后是HTTP / 2可以实现的新模型。

交付模式

如前一节所述,HTTP / 1.1和HTTP / 2共享语义,确保两个协议中服务器和客户端之间传递的请求和响应使用标题和正文的传统格式消息到达目的地,使用熟悉的方法,如GETPOST 但是当HTTP / 1.1在纯文本消息中传输它们时,HTTP / 2将这些转换为二进制,从而允许显着不同的传递模型可能性。 在本节中,我们将首先简要介绍HTTP / 1.1如何尝试通过其交付模型优化效率以及由此产生的问题,然后是HTTP / 2的二进制框架层的优点以及优先级的描述要求。

HTTP / 1.1 - 流水线和行头阻塞

客户端在HTTP GET请求上收到的第一个响应通常不是完全呈现的页面。 相反,它包含指向所请求页面所需的其他资源的链接。 客户端发现只有在下载页面后,页面的完整呈现才需要来自服务器的这些额外资源。 因此,客户端将不得不提出额外的请求来检索这些资源。 在HTTP / 1.0中,客户端必须在每次新请求时打破并重新建立TCP连接,这在时间和资源方面都是代价高昂的。

HTTP / 1.1通过引入持久连接和流水线来解决这个问题。 对于持久连接,HTTP / 1.1假定TCP连接应保持打开,除非直接告知关闭。 这允许客户端在同一连接上发送多个请求,而无需等待每个请求的响应,从而大大提高了HTTP / 1.1 over HTTP / 1.0的性能。

不幸的是,这种优化策略存在天然的瓶颈。 由于多个数据包在前往同一目的地时不能相互传递,因此存在无法检索其所需资源的队列头部的请求将阻止其后面的所有请求的情况。 这称为线头(HOL)阻塞 ,并且是优化HTTP / 1.1中的连接效率的重要问题。 添加单独的并行TCP连接可以缓解此问题,但客户端和服务器之间可能存在的并发TCP连接数存在限制,并且每个新连接都需要大量资源。

这些问题是HTTP / 2开发人员的头脑,他们建议使用上述二进制框架层来解决这些问题,这个主题将在下一节中详细介绍。

HTTP / 2 - 二进制成帧层的优点

在HTTP / 2中,二进制成帧层对请求/响应进行编码,并将其切换为较小的信息包,从而大大提高了数据传输的灵活性。

让我们仔细看看它是如何工作的。 与HTTP / 1.1相反,HTTP / 1.1必须使用多个TCP连接来减少HOL阻塞的影响,HTTP / 2在两台机器之间建立单个连接对象。 在此连接中,存在多个数据流 每个流由熟悉的请求/响应格式的多个消息组成。 最后,这些消息中的每一个都被分成称为帧的较小单元:

流,消息和框架

在最精细的层面上,通信信道由一堆二进制编码的帧组成,每个帧都标记为特定的流。 识别标签允许连接在传输期间交错这些帧,并在另一端重新组装它们。 交错的请求和响应可以并行运行,而不会阻塞它们后面的消息,这个过程称为多路复用 多路复用通过确保没有消息必须等待另一个消息完成来解决HTTP / 1.1中的行头阻塞问题。 这也意味着服务器和客户端可以发送并发请求和响应,从而实现更好的控制和更高效的连接管理。

由于多路复用允许客户端并行构造多个流,因此这些流只需要使用单个TCP连接。 通过减少整个网络中的内存和处理占用空间,每个源具有单个持久连接可以改进HTTP / 1.1。 这导致更好的网络和带宽利用率,从而降低总体运营成本。

单个TCP连接还可以提高HTTPS协议的性能,因为客户端和服务器可以为多个请求/响应重用相同的安全会话。 在HTTPS中,在TLS或SSL握手期间,双方同意在整个会话期间使用单个密钥。 如果连接中断,则会启动新会话,需要新生成的密钥以进行进一步通信。 因此,维护单个连接可以大大减少HTTPS性能所需的资源。 请注意,虽然HTTP / 2规范不强制要求使用TLS层,但许多主流浏览器仅支持使用HTTPS的HTTP / 2。

尽管二进制成帧层中固有的多路复用解决了HTTP / 1.1的某些问题,但是等待相同资源的多个流仍然可能导致性能问题。 然而,HTTP / 2的设计通过使用流优先级来考虑这一点,我们将在下一节讨论该主题。

HTTP / 2 - 流优先级

流优先级不仅解决了竞争相同资源的请求的可能问题,还允许开发人员定制请求的相对权重以更好地优化应用程序性能。 在本节中,我们将分解此优先级的过程,以便更好地了解如何利用HTTP / 2的此功能。

如您所知,二进制成帧层将消息组织为并行数据流。 当客户端向服务器发送并发请求时,它可以通过为每个流分配1到256之间的权重来确定其请求的响应的优先级。 数字越大表示优先级越高。 除此之外,客户端还通过指定其所依赖的流的ID来说明每个流对另一个流的依赖性。 如果省略父标识符,则认为该流依赖于根流。 如下图所示:

流优先级

在图示中,通道包含六个流,每个流具有唯一ID并与特定权重相关联。 流1没有与之关联的父ID,并且默认情况下与根节点关联。 所有其他流都标记了一些父ID。 每个流的资源分配将基于它们所持有的权重以及它们所需的依赖性。 例如,在图中已被分配了相同权重和相同父流的流5和6将具有用于资源分配的相同优先级。

服务器使用此信息创建依赖关系树,允许服务器确定请求将检索其数据的顺序。 根据上图中的流,依赖树将如下:

依赖树

在此依赖关系树中,流1依赖于根流,并且没有从根导出的其他流,因此所有可用资源将在其他流之前分配给流1。 由于树指示流2取决于流1的完成,因此流2将不会继续直到流1任务完成。 现在,让我们看一下流3和4.这两个流都依赖于流2.如在流1的情况下,流2将在流3和流4之前获得所有可用资源。在流2完成其任务之后,流3和4将获得资源; 如它们的权重所示,它们以2:4的比例分开,从而为流4产生更大的资源块。最后,当流3完成时,流5和6将获得相等部分的可用资源。 这可以在流4完成其任务之前发生,即使流4接收到更多的资源块; 一旦较高级别的依赖流完成,就允许较低级别的流启动。

作为应用程序开发人员,您可以根据需要在请求中设置权重。 例如,在网页上提供缩略图图像后,您可以为较高分辨率加载图像分配较低的优先级。 通过提供这种权重分配功能,HTTP / 2使开发人员能够更好地控制网页呈现。 该协议还允许客户端在运行时更改依赖关系并重新分配权重以响应用户交互。 然而,重要的是要注意,如果某个流被阻止访问特定资源,则服务器可以自己更改分配的优先级。

缓冲区溢出

在两台计算机之间的任何TCP连接中,客户端和服务器都有一定数量的缓冲区空间可用于保存尚未处理的传入请求。 除了下游和上游连接的不均匀速度之外,这些缓冲器还提供了解决许多或特别大的请求的灵活性。

但是,有些情况下缓冲区是不够的。 例如,由于有限的缓冲区大小或较低的带宽,服务器可能以客户端应用程序无法处理的速度推送大量数据。 同样,当客户端将巨大的图像或视频上传到服务器时,服务器缓冲区可能会溢出,从而导致一些额外的数据包丢失。

为了避免缓冲区溢出,流量控制机制必须防止发送方用数据压倒接收方。 本节将概述HTTP / 1.1和HTTP / 2如何根据不同的交付模型使用此机制的不同版本来处理流量控制。

HTTP / 1.1

在HTTP / 1.1中,流控制依赖于底层TCP连接。 当此连接启动时,客户端和服务器都使用其系统默认设置建立其缓冲区大小。 如果接收器的缓冲区部分地填充了数据,它将告诉发送方它的接收窗口 ,即其缓冲区中剩余的可用空间量。 该接收窗口在称为ACK分组的信号中通告,该ACK分组是接收器发送以确认其接收到打开信号的数据分组。 如果此通告的接收窗口大小为零,则发送方将不再发送数据,直到客户端清除其内部缓冲区,然后请求恢复数据传输。 这里需要注意的是,使用基于底层TCP连接的接收窗口只能在连接的任何一端实现流控制。

因为HTTP / 1.1依赖传输层来避免缓冲区溢出,所以每个新的TCP连接都需要一个单独的流控制机制。 但是,HTTP / 2在单个TCP连接中复用流,并且必须以不同的方式实现流控制。

HTTP / 2

HTTP / 2在单个TCP连接中复用数据流。 结果,在TCP连接级别上接收窗口不足以调节各个流的传送。 HTTP / 2通过允许客户端和服务器实现自己的流控制而不是依赖传输层来解决此问题。 应用层传递可用的缓冲区空间,允许客户端和服务器在多路复用流的级别上设置接收窗口。 在初始连接之后,可以通过WINDOW_UPDATE帧修改或维护此精细流量控制。

由于该方法控制应用层级别上的数据流,因此流量控制机制不必在调整接收窗口之前等待信号到达其最终目的地。 中间节点可以使用流控制设置信息来确定它们自己的资源分配并相应地进行修改。 这样,每个中间服务器都可以实现自己的自定义资源策略,从而提高连接效率。

在创建适当的资源策略时,流控制的这种灵活性可能是有利的。 例如,客户端可以获取图像的第一次扫描,将其显示给用户,并允许用户在获取更多关键资源的同时预览它。 一旦客户端获取这些关键资源,浏览器将继续检索图像的剩余部分。 将流控制的实现推迟到客户端和服务器可以因此改善Web应用程序的感知性能。

在流控制和前面部分中提到的流优先级方面,HTTP / 2提供了更详细的控制级别,从而开启了更大优化的可能性。 下一节将解释协议特有的另一种方法,它可以以类似的方式增强连接:使用服务器推送预测资源请求。

预测资源请求

在典型的Web应用程序中,客户端将发送GET请求并以HTML格式接收页面,通常是站点的索引页面。 在检查索引页面内容时,客户端可能会发现它需要获取其他资源,例如CSS和JavaScript文件,以便完全呈现页面。 客户端仅在收到来自其初始GET请求的响应后才确定它需要这些额外资源,因此必须提出其他请求以获取这些资源并完成将页面放在一起。 这些额外的请求最终会增加连接加载时间。

但是,有这个问题的解决方案:由于服务器事先知道客户端将需要其他文件,服务器可以通过在请求它们之前将这些资源发送到客户端来节省客户端时间。 HTTP / 1.1和HTTP / 2有不同的实现策略,每个策略将在下一节中描述。

HTTP / 1.1 - 资源内联

在HTTP / 1.1中,如果开发人员事先知道客户端机器需要呈现哪些额外资源来呈现页面,他们可以使用称为资源内联的技术将所需资源直接包含在服务器发送的HTML文档中以响应初始GET请求。 例如,如果客户端需要特定的CSS文件来呈现页面,那么内联CSS文件将在客户端请求之前为客户端提供所需的资源,从而减少客户端必须发送的请求总数。

但资源内联存在一些问题。 在HTML文档中包含资源对于较小的基于文本的资源是可行的解决方案,但是非文本格式的较大文件会极大地增加HTML文档的大小,这最终会降低连接速度并使获得的原始优势无效从使用这种技术。 此外,由于内联资源不再与HTML文档分离,因此客户端没有机制拒绝它已有的资源,或者将资源放在其缓存中。 如果多个页面需要资源,则每个新的HTML文档将在其代码中具有相同的内联资源,从而导致更大的HTML文档和更长的加载时间,而不是在开始时简单地缓存资源。

因此,资源内联的一个主要缺点是客户端无法分离资源和文档。 需要更精细的控制来优化连接,HTTP / 2需要通过服务器推送来满足。

HTTP / 2 - 服务器推送

由于HTTP / 2允许对客户端的初始GET请求进行多个并发响应,因此服务器可以将资源与请求的HTML页面一起发送到客户端,在客户端请求之前提供资源。 此过程称为服务器推送 通过这种方式,HTTP / 2连接可以实现资源内联的相同目标,同时保持推送资源和文档之间的分离。 这意味着客户端可以决定缓存或拒绝与主HTML文档分开的推送资源,从而解决资源内联的主要缺点。

在HTTP / 2中,当服务器发送PUSH_PROMISE帧以通知客户端它将推送资源时,此过程开始。 此框架仅包含消息的标头,并允许客户端提前知道服务器将推送哪个资源。 如果已经缓存了资源,则客户端可以通过发送RST_STREAM帧来拒绝推送。 PUSH_PROMISE帧还可以防止客户端向服务器发送重复请求,因为它知道服务器将推送哪些资源。

这里需要注意的是,服务器推送的重点是客户端控制。 如果客户端需要调整服务器推送的优先级,甚至禁用它,它可以随时发送SETTINGS帧来修改此HTTP / 2功能。

虽然此功能具有很大的潜力,但服务器推送并不总是优化Web应用程序的答案。 例如,即使客户端已经缓存了资源,某些Web浏览器也无法始终取消推送的请求。 如果客户端错误地允许服务器发送重复资源,则服务器推送可能会不必要地耗尽连接。 最后,服务器推送应由开发人员自行决定使用。 有关如何战略性地使用服务器推送和优化Web应用程序的更多信息,请查看Google开发的PRPL模式 要了解有关服务器推送可能出现的问题的更多信息,请参阅Jake Archibald的博客文章HTTP / 2推送比我想象的更难

压缩

优化Web应用程序的常用方法是使用压缩算法来减少在客户端和服务器之间传输的HTTP消息的大小。 HTTP / 1.1和HTTP / 2都使用此策略,但前者存在禁止压缩整个消息的实现问题。 以下部分将讨论为什么会出现这种情况,以及HTTP / 2如何提供解决方案。

HTTP / 1.1

gzip这样的程序长期以来一直用于压缩HTTP消息中发送的数据,尤其是减少CSS和JavaScript文件的大小。 但是,消息的标题组件始终以纯文本形式发送。 虽然每个标头都非常小,但是这种未压缩数据的负担在连接上的重量越来越大,因为需要更多的请求,特别是对需要许多不同资源并因此需要许多不同资源请求的复杂的API密集型Web应用程序进行处罚。 此外,使用cookie有时会使标头更大,从而增加了对某种压缩的需求。

为了解决这个瓶颈,HTTP / 2使用HPACK压缩来缩小标头的大小,这个主题将在下一节中进一步讨论。

HTTP / 2

在HTTP / 2中一次又一次出现的主题之一是它能够使用二进制框架层来更好地控制细节。 在头压缩方面也是如此。 HTTP / 2可以从其数据中分割标头,从而生成标头帧和数据帧。 然后,HTTP / 2特定的压缩程序HPACK可以压缩该头部帧。 该算法可以使用霍夫曼编码对头元数据进行编码,从而大大减小其大小。 另外,HPACK可以跟踪先前传送的元数据字段,并根据客户端和服务器之间共享的动态改变的索引进一步压缩它们。 例如,请执行以下两个请求:

请求#1
method:     GET
scheme:     https
host:       example.com
path:       /academy
accept:     /image/jpeg
user-agent: Mozilla/5.0 ...
请求#2
method:     GET
scheme:     https
host:       example.com
path:       /academy/images
accept:     /image/jpeg
user-agent: Mozilla/5.0 ...

这些请求中的各个字段(如methodschemehostacceptuser-agent )具有相同的值; 只有path字段使用不同的值。 结果,当发送Request #2 ,客户端可以使用HPACK仅发送重建这些公共字段所需的索引值并重新编码path字段。 生成的标题框架如下:

请求#1的标头帧
method:     GET
scheme:     https
host:       example.com
path:       /academy
accept:     /image/jpeg
user-agent: Mozilla/5.0 ...
请求#2的标头帧
path:       /academy/images

使用HPACK和其他压缩方法,HTTP / 2提供了一项可以减少客户端 - 服务器延迟的功能。

结论

从这个逐点分析可以看出,HTTP / 2在许多方面与HTTP / 1.1不同,其中一些功能提供了更高级别的控制,可用于更好地优化Web应用程序性能和其他功能,只需改进以前的协议。 现在您已经了解了两种协议之间的差异,您可以考虑HTTP / 2中的多路复用,流优先级,流控制,服务器推送和压缩等因素将如何影响Web开发的变化。

如果您希望在HTTP / 1.1和HTTP / 2之间看到性能比较,请查看此Google演示 ,该演示将比较不同延迟的协议。 请注意,在计算机上运行测试时,页面加载时间可能会因测试时可用的带宽,客户端和服务器资源等因素而异。 如果您想研究更详尽的测试结果,请查看文章HTTP / 2 - 真实世界性能测试和分析 最后,如果您想探索如何构建现代Web应用程序,您可以按照我们的如何使用Django和React在Ubuntu 18.04上构建现代Web应用程序来管理客户信息教程,或者设置您自己的HTTP / 2服务器我们如何在Ubuntu 16.04教程中使用HTTP / 2支持设置Nginx


分享按钮