HTTP/1.1 与 HTTP/2:区别何在?

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

介绍

从1997年发布HTTP/1.1到最近,对该协议进行了很少的修订,但在2015年,一种名为HTTP/2的重新构想的版本开始使用,它提供了减少延迟的几种方法,特别是在处理移动平台和服务器密集型图形和视频时。HTTP/2自那时起越来越受欢迎,一些估计表明,全世界约三分之一的网站支持它。

阅读本文后,您将了解 HTTP/1.1 和 HTTP/2 之间的主要差异,专注于 HTTP/2 所采用的技术变化,以实现更高效的 Web 协议。

背景

为了定义 HTTP/2 对 HTTP/1.1 的具体变化,让我们先从高层次来看一下每一个版本的历史发展和基本运作。

HTTP 或 1.1

HTTP 是由 Timothy Berners-Lee 于 1989 年作为世界网的通信标准开发的顶级应用程序协议,它在客户端计算机与本地或远程 Web 服务器之间交换信息,在这个过程中,客户端通过调用一个 methodGETPOST来向服务器发送基于文本的请求。

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

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

此请求使用GET方法,请求来自Host:后列出的主机服务器的数据。 响应此请求时,example.com Web 服务器会向请求客户端返回一个 HTML 页面,以及 HTML 中所要求的任何图像、风格表或其他资源。

你可以把这个交换的请求和响应作为一个单一的 application layer 的互联网协议堆栈,坐在上面的 transfer layer (通常使用传输控制协议或TCP) 和 networking layers (使用互联网协议或IP):

Internet Protocol Stack

有很多关于这个堆栈的较低水平的讨论,但为了获得对HTTP/2的高层理解,你只需要知道这个抽象层模型和HTTP在哪里。

有了这个基本的HTTP/1.1概述,我们现在可以重新计算HTTP/2的早期发展。

HTTP / 2

HTTP/2 起源于 SPDY 协议,主要是在 Google 开发的,目的是通过使用压缩、重叠和优先级等技术来减少网页负载延迟。当 IETF(Internet Engineering Task Force)的工作小组 httpbis(LINK0)组合标准时,HTTP/2 作为 HTTP/2 的模板,最终在 2015 年 5 月发布了 HTTP/2。从一开始,许多浏览器都支持这种标准化努力,包括 Chrome、Opera、Internet Explorer 和 Safari。

从技术的角度来看,区分 HTTP/1.1 和 HTTP/2 的最重要的特征之一是二进制框架层,可以被认为是互联网协议堆栈中的应用层的一部分。 与 HTTP/1.1 不同,它将所有请求和响应保持在纯文本格式中,HTTP/2 使用二进制框架层将所有消息嵌入二进制格式中,同时保持 HTTP 语义,如口语,方法和标题。 应用程序级 API 仍然会在常规 HTTP 格式中创建消息,但底层将这些消息转换为二进制。

将消息转换为二进制允许 HTTP/2 尝试在 HTTP/1.1 中无法提供的数据交付的新方法,这是两个协议之间的实际差异的根源。

交付模型

正如上一节所提到的,HTTP/1.1 和 HTTP/2 共享语义,确保服务器和客户端之间的请求和响应以传统的标题和器官格式来到达目的地,使用熟悉的方法,如GETPOST。但是,虽然 HTTP/1.1 将这些信息转移为简单的文本消息,HTTP/2 将这些信息编码为二进制,允许显著不同的交付模式可能性。

HTTP/1.1 - 管道和线头封锁

客户端在 HTTP GET 请求中获得的第一个响应往往不是完全渲染的页面,而是包含链接到所请求的页面所需的额外资源,客户端发现页面的完整渲染只需要服务器下载该页面之后的这些额外资源,因此客户端必须提出额外的请求以获取这些资源,在 HTTP/1.0 中,客户端必须在每一个新请求时断开并重建 TCP 连接,这在时间和资源方面都是昂贵的。

HTTP/1.1 通过引入持久连接和管道来解决这个问题. 对于持久连接,HTTP/1.1 假定 TCP 连接应该保持开放,除非直接被告知关闭。

不幸的是,这种优化策略存在一个自然的瓶颈,因为在前往同一个目的地时,多个数据包无法彼此传递,所以有情况下,在排队头的请求无法检索所需的资源将阻止其背后的所有请求,这被称为 head-of-line (HOL) blocking,并且在 HTTP/1.1 中优化连接效率是一个重大问题。

这些问题正处于HTTP/2开发人员的头脑前沿,他们建议使用上述二进制框架层来修复这些问题,您将在下一节了解更多。

HTTP/2 - 二进制框架层的优点

在 HTTP/2 中,二进制框架层编码请求/响应,并将其切成更小的信息包,大大增加了数据传输的灵活性。

让我们仔细看看这是如何工作的。 与 HTTP/1.1 不同,它必须使用多个 TCP 连接来减少 HOL 阻断的效果,HTTP/2 建立了两个机器之间的单个连接对象。 在这种连接中,有多个 streams 数据。 每个流由熟悉的请求/响应格式中的多个消息组成。

Streams, Messages, and Frames

在最细微的层面上,通信渠道由一堆二进制编码的框架组成,每个框架都标记为特定流程。识别标签允许连接在传输过程中将这些框架交叉并在另一端重新组装。交叉请求和响应可以并行运行,而不会阻止它们背后的消息,这个过程称为 _multiplexing。

由于 multiplexing 允许客户端并行构建多个流,这些流只需要使用单个 TCP 连接. 每个源头有一个单一的永久连接可以通过减少整个网络的内存和处理足迹来改善 HTTP/1.1。

单一的 TCP 连接也提高了 HTTPS 协议的性能,因为客户端和服务器可以重复使用相同的安全会话进行多个请求/响应。在 HTTPS 中,在 TLS 或 SSL 握手过程中,双方都同意在整个会话中使用单一的密钥。如果连接断开,新的会话开始,需要新生成的密钥进行进一步的通信。因此,保持单一的连接可以大大降低 HTTPS 性能所需的资源。 请注意,尽管 HTTP/2 规格不要求使用 TLS 层,但许多主要的浏览器只支持 HTTP/2 和 HTTPS。

虽然二进制框架层中固有的倍增解决了 HTTP/1.1 的某些问题,但等待相同资源的多个流仍然可能导致性能问题。

HTTP/2 - 流优先级

流优先化不仅解决了竞争同一资源的请求的可能问题,还允许开发人员定制请求的相对重量,以便更好地优化应用性能。

正如你现在所知道的,二进制框架层将消息组织成并行数据流。当客户端向服务器发送并行请求时,它可以将所请求的响应优先分配为1至256之间的重量。较高的数字表示更高的优先级。除此之外,客户端还通过指定其依赖的流标识符来表示每个流的依赖性。

Stream Prioritization

在示例中,频道包含六个流,每个流都有一个独特的ID,并与一个特定的重量相关联。 流1没有与它相关联的母体ID,并且默认情况下与根节点相关联。 所有其他流都有某些母体ID标记。 每个流的资源分配将基于它们所持有的重量和所需的依赖性。

服务器使用此信息创建一个依赖树,允许服务器确定请求将获取数据的顺序. 根据上图中的流,依赖树将如下:

Dependency Tree

在这种依赖树中,流1取决于根流,并且没有其他流源于根,所以所有可用的资源将分配到流1之前的其他流。由于树表明流2取决于流1的完成,流2不会继续直到流1任务完成。现在,让我们看看流3和4都取决于流2,就像流1的情况下一样,流2将获得流3和4之前的所有可用的资源。在流2完成任务后,流3和4将获得资源;这些资源被分割为2:4的比率,如其重量所示,导致流4的资源的较高部分。最后,当流3结束时,流5和6将获得可用的资源以平等的部分。在流4完成任务之前,这种情况可能会发生,即使流4也获得了更高的资源;在较低的水平上流被允许

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

泡沫过流

在两台机器之间的任何TCP连接中,客户端和服务器都有一定数量的缓冲空间,可容纳尚未处理的传入请求,这些缓冲提供了对大量或特别大的请求的灵活性,以及下游和上游连接的不均匀速度。

例如,服务器可能会以客户端应用程序由于缓冲尺寸有限或带宽较低而无法应对的速度推动大量数据。

为了避免缓冲过流,流量控制机制必须防止发件人用数据压倒接收器,本节将提供HTTP/1.1和HTTP/2如何使用该机制的不同版本来根据其不同的交付模型来处理流量控制。

HTTP 或 1.1

在 HTTP/1.1 中,流量控制依赖于底层的 TCP 连接。当这种连接启动时,客户端和服务器都使用系统默认设置建立了缓冲尺寸。如果接收器的缓冲部分充满了数据,它会告诉发件人其 receive window,即在缓冲中剩余的可用空间的数量。这个接收窗口被宣传成一个称为 ACK packet 的信号,这是接收器发送的数据包,以确认接收器接收了开启信号。如果这个广告的接收窗口尺寸为零,则发件人将不会再发送更多的数据,直到客户端清理内部缓冲,然后要求恢复数据传输。这里重要的是要注意,使用基于底层的 TCP 连接的接收窗口

由于 HTTP/1.1 依赖传输层来避免缓冲过流,所以每一个新的 TCP 连接都需要一个单独的流量控制机制。

HTTP / 2

HTTP/2 在单一 TCP 连接中 multiplexer数据流. 因此,在 TCP 连接级别的接收窗口不足以调节单个流的交付。 HTTP/2 通过允许客户端和服务器实施自己的流量控制,而不是依赖运输层来解决这个问题。

由于这种方法在应用层级控制数据流量,因此流量控制机制在调整接收窗口之前不必等到信号到达最终目的地。中间节点可以使用流量控制设置信息来确定自己的资源配置并相应修改。

这种流量控制的灵活性在创建适当的资源策略时可以有利。例如,客户端可以检索图像的第一个扫描,向用户显示,并允许用户预览它,同时检索更多关键资源。

在流量控制和流量优先级方面,HTTP/2提供了更详细的控制级别,从而打开了更大的优化可能性。

预测资源请求

在一个典型的Web应用程序中,客户端会发送一个GET请求并收到一个页面在HTML中,通常是网站的索引页面。在检查索引页面的内容时,客户端可能会发现它需要收集额外的资源,如CSS和JavaScript文件,以便完全渲染页面。

然而,这个问题有解决方案:由于服务器事先知道客户端将需要额外的文件,服务器可以通过将这些资源发送给客户端,从而节省客户端的时间。

HTTP/1.1 - 资源内置

在 HTTP/1.1 中,如果开发人员提前知道客户端机器需要哪些额外资源来渲染页面,他们可以使用一种称为 resource inlining 的技术,将所需资源直接包含在服务器发送的HTML文档中,以响应最初的GET请求。

但是,包含资源在HTML文档中是较小的、基于文本的资源的可行解决方案,但在非文本格式中更大的文件可以大大增加HTML文档的大小,这最终可以降低连接速度,并取消使用此技术获得的原有优势。 此外,由于嵌入资源不再与HTML文档分开,客户端没有机制来减少它已经拥有的资源,或将资源放置在其缓存中。

因此,资源嵌入的一个主要缺点是,客户端无法将资源和文档分开,需要更精细的控制级别来优化连接,这是HTTP/2寻求满足服务器推送的需求。

HTTP/2 - 服务器推送

由于 HTTP/2 允许多个同时响应客户端的初始GET请求,服务器可以将资源发送到客户端以及所请求的 HTML 页面,在客户端请求之前提供资源. 这种过程被称为 server push

在 HTTP/2 中,此过程始于服务器发送一个PUSH_PROMISE框架来通知客户端,它将推一个资源. 此框架仅包含消息的标题,并允许客户端提前知道服务器将推哪个资源。

如果客户端需要调整服务器推送的优先级,甚至禁用它,它可以随时发送一个设置框架来修改这个HTTP/2功能。

虽然这个功能有很多潜力,但服务器推送并不总是优化您的 Web 应用程序的答案。例如,某些 Web 浏览器不能总是取消推送请求,即使客户端已经缓存了资源。如果客户端错误地允许服务器发送重复资源,服务器推送可能会不必要地使用连接。最后,服务器推送应根据开发人员的判断使用。有关如何战略性地使用服务器推送和优化 Web 应用程序的更多信息,请参阅 Google 开发的 PRPL 模式

压缩

优化 Web 应用程序的一种常见方法是使用压缩算法来减少客户端和服务器之间移动的 HTTP 消息的大小 HTTP/1.1 和 HTTP/2 都使用这种策略,但前者存在实施问题,禁止压缩整个消息。

HTTP 或 1.1

gzip这样的程序长期以来一直被用来压缩在 HTTP 消息中发送的数据,特别是减少 CSS 和 JavaScript 文件的大小。 然而,消息的标题组成部分总是以简单的文本发送。 尽管每个标题都相当小,但这些未压缩的数据的负担在连接上越来越重,随着更多请求的发送,这可能会惩罚复杂的,API 重的 Web 应用程序,这些应用程序需要许多不同的资源,因此需要许多不同的资源请求。

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

HTTP / 2

HTTP/2中一再出现的主题之一是它能够使用二进制框架层来显示更精细的细节更大的控制权。同样在头条压缩方面也是如此。 HTTP/2 可以将头条从数据中分开,从而产生头条框架和数据框架。 HTTP/2 特定的压缩程序 HPACK可以压缩这个头条框架。 这种算法可以使用 Huffman 编码来编码头条数据,从而大大减少其大小。

1[label Request #1]
2method:		GET
3scheme:		https
4host:		example.com
5path:		/academy
6accept:		/image/jpeg
7user-agent:	Mozilla/5.0 ...
1[label Request #2]
2method:		GET
3scheme:		https
4host:		example.com
5path:		/academy/images
6accept:		/image/jpeg
7user-agent:	Mozilla/5.0 ...

这些请求中的各种字段,如方法,方案,主机,接受用户代理,具有相同的值;只有路径字段使用不同的值。 因此,在发送请求 #2时,客户端可以使用 HPACK 发送仅用于重构这些常见字段和重新编码路径字段所需的索引值。

1[label Header Frame for Request #1]
2method:		GET
3scheme:		https
4host:		example.com
5path:		/academy
6accept:		/image/jpeg
7user-agent:	Mozilla/5.0 ...
1[label Header Frame for Request #2]
2path:		/academy/images

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

结论

正如你可以从这个点对点的分析中看到的,HTTP/2在许多方面不同于HTTP/1.1,有些功能提供了更高的控制水平,可以用来更好地优化Web应用程序的性能和其他功能,仅仅是通过改进上一个协议。

如果您想看到 HTTP/1.1 和 HTTP/2 之间的性能比较,请查看此 Google 演示 比较不同延迟的协议。 请注意,当您在计算机上运行测试时,页面加载时间可能取决于几种因素,例如在测试时可用的带宽、客户端和服务器资源等。 如果您想研究更全面的测试结果,请参阅文章 HTTP/2 – A Real-World Performance Test and Analysis )。 最后,如果您想探索如何构建现代Web应用程序,您可以遵循我们的 如何构建现代Web应用程序以管理客户信息与Django和React在Ubuntu 18.04教程,或使用我们的 [How To Set Up With NgxP HTTP

Published At
Categories with 技术
comments powered by Disqus