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

↘锁芯ラ 提交于 2019-12-01 12:15:30
介绍 超文本传输​​协议(HTTP)是一种应用协议,自1989年发明以来,它一直是事实上在万维网上进行通信的标准。从1997年发布HTTP / 1.1到最近,对它的修改很少。协议。但是在2015年,重新构想的版本称为HTTP / 2投入使用,它提供了几种减少延迟的方法,尤其是在处理移动平台以及服务器密集型图形和视频时。此后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 HTTP由Timothy Berners-Lee于1989年开发,作为万维网的通信标准,HTTP是一种顶级应用程序协议,它在客户端计算机与本地或远程Web服务器之间交换信息。在此过程中,客户端通过调用类似或的方法向服务器发送基于文本的请求。作为响应,服务器将HTML页面之类的资源发送回客户端。GETPOST 例如,假设您正在访问域中的网站www.example.com。当您导航到该URL时,计算机上的Web浏览器会以基于文本的消息的形式发送HTTP请求,类似于以下所示: ``` GET /index.html HTTP/1.1 Host: www.example.com ``` 该请求使用的GET方法,该方法从后面列出的主机服务器中请求数据Host:。响应此请求,example.comWeb服务器将HTML页面返回到发出请求的客户端,此外还包含HTML中要求的任何图像,样式表或其他资源。请注意,在第一次数据调用中,并非所有资源都会返回给客户端。请求和响应将在服务器和客户端之间来回移动,直到Web浏览器收到在屏幕上呈现HTML页面内容所需的所有资源为止。 您可以将这种请求和响应的交换视为Internet协议栈的单个应用程序层,它位于传输层(通常使用传输控制协议或TCP)和网络层(使用Internet协议或IP )之上): ![](https://img2018.cnblogs.com/blog/1814598/201910/1814598-20191016133942638-1909944572.png) 关于此堆栈的较低层,有很多要讨论的内容,但是为了获得对HTTP / 2的高层了解,您只需要知道此抽象层模型以及HTTP进入其中的位置即可。 借助HTTP / 1.1的基本概述,我们现在可以继续讲述HTTP / 2的早期开发。 #### HTTP / 2 HTTP / 2最初是SPDY协议,最初由Google开发,旨在通过使用压缩,复用和优先级等技术来减少网页加载延迟。当[IETF(互联网工程任务组)](https://www.ietf.org/)的超文本传输​​协议工作组httpbis 将该标准放在一起时,此协议充当HTTP / 2的模板,并最终在2015年5月发布了HTTP / 2。从一开始,许多浏览器支持这项标准化工作,包括Chrome,Opera,Internet Explorer和Safari。自2015年以来,部分原因是由于该浏览器的支持,该协议的采用率非常高,新站点中的采用率尤其高。 从技术角度来看,区别HTTP / 1.1和HTTP / 2的最重要功能之一是二进制框架层,可以将其视为Internet协议栈中应用程序层的一部分。与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共享语义,使用熟悉的方法(如GET和),确保在两种协议之间在服务器和客户端之间传输的请求和响应作为具有标题和正文的传统格式的消息到达目的地POST。但是,尽管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相对于HTTP / 1.0的性能。 不幸的是,这种优化策略存在一个自然的瓶颈。由于多个数据包在到达同一目的地时无法相互传递,因此在某些情况下,队列开头的无法检索其所需资源的请求将阻止其后的所有请求。这被称为行头(HOL)阻止,并且在优化HTTP / 1.1中的连接效率方面是一个重大问题。添加单独的并行TCP连接可以缓解此问题,但是客户端和服务器之间可能存在的并发TCP连接的数量受到限制,并且每个新连接都需要大量资源。 这些问题在HTTP / 2开发人员的思想中居首位,他们提议使用上述二进制框架层来解决这些问题,您将在下一节中详细了解该主题。 #### HTTP / 2 —二进制框架层的优点 在HTTP / 2中,二进制帧层对请求/响应进行编码,并将其切成较小的信息包,从而大大提高了数据传输的灵活性。 让我们仔细看看它是如何工作的。与HTTP / 1.1(必须使用多个TCP连接来减轻HOL阻塞的影响)相反,HTTP / 2在两台计算机之间建立了一个连接对象。在此连接内,有多个数据流。每个流由熟悉的请求/响应格式的多个消息组成。最后,每条消息都分成较小的单元,称为框架: ![](https://img2018.cnblogs.com/blog/1814598/201910/1814598-20191016133942869-479138638.png) 从最细粒度的角度讲,通信通道由一堆二进制编码的帧组成,每个帧都标记到特定的流。识别标签允许连接在传输过程中交织这些帧,并在另一端重新组装它们。交错的请求和响应可以并行运行,而不会阻塞后面的消息,这一过程称为multiplexing。通过确保没有消息等待其他消息完成,多路复用解决了HTTP / 1.1中的行头阻塞问题。这也意味着服务器和客户端可以发送并发请求和响应,从而实现更好的控制和更有效的连接管理。 由于多路复用允许客户端并行构造多个流,因此这些流仅需要利用单个TCP连接。每个起点只有一个持久连接,可以通过减少整个网络的内存和处理占用空间来改善HTTP / 1.1。这导致更好的网络和带宽利用率,从而降低了总体运营成本。 单个TCP连接还可以提高HTTPS协议的性能,因为客户端和服务器可以将相同的安全会话重用于多个请求/响应。在HTTPS中,在TLS或SSL握手期间,双方都同意在整个会话过程中使用单个密钥。如果连接断开,则新的会话开始,需要新生成的密钥用于进一步的通信。因此,维护单个连接可以大大减少HTTPS性能所需的资源。请注意,尽管HTTP / 2规范没有强制要求使用TLS层,但许多主流浏览器仅支持HTTP / 2和HTTPS。 尽管二进制框架层中固有的多路复用解决了HTTP / 1.1的某些问题,但是等待相同资源的多个流仍然会导致性能问题。HTTP / 2的设计考虑了这一点,但是,通过使用流优先级,我们将在下一节中讨论这个主题。 #### HTTP / 2 —流优先级 流优先级划分不仅解决了争用同一资源的请求的可能问题,而且还允许开发人员自定义请求的相对权重,以更好地优化应用程序性能。在本节中,我们将分解优先级划分过程,以便更好地了解如何利用HTTP / 2的此功能。 众所周知,二进制框架层将消息组织成并行的数据流。当客户端将并发请求发送到服务器时,它可以通过为每个流分配1到256之间的权重来区分请求的响应的优先级。数字越高表示优先级越高。除此之外,客户端还通过指定流所依赖的流的ID来声明每个流对另一流的依赖性。如果省略了父标识符,则认为该流依赖于根流。下图对此进行了说明: ![](https://img2018.cnblogs.com/blog/1814598/201910/1814598-20191016133943078-411293586.png) 在图示中,该频道包含六个流,每个流具有唯一的ID并与特定的权重关联。流1没有与其关联的父ID,并且默认情况下与根节点关联。所有其他流都标记了一些父ID。每个流的资源分配将基于它们所拥有的权重及其所需的依赖关系。例如,在图中已分配了相同权重和相同父流的流5和6,将具有相同的资源分配优先级。 服务器使用此信息来创建依赖关系树,该依赖关系树允许服务器确定请求检索其数据的顺序。根据上图中的流,依赖关系树如下: ![](https://img2018.cnblogs.com/blog/1814598/201910/1814598-20191016133943308-1193016608.png) 在此依赖关系树中,流1依赖于根流,并且没有其他从根派生的流,因此所有可用资源将在其他流之前分配给流1。由于树表明流2取决于流1的完成,因此直到流1任务完成,流2才继续进行。现在,让我们看一下流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数据包的信号中公告,这是接收器发送的数据包,用于确认已接收到打开信号。如果此公告的接收窗口大小为零,则发送方将不再发送任何数据,直到客户端清除其内部缓冲区,然后请求恢复数据传输为止。在此处需要注意的重要一点是,使用基于基础TCP连接的接收窗口只能在连接的任一端实现流控制。 因为HTTP / 1.1依赖传输层来避免缓冲区溢出,所以每个新的TCP连接都需要单独的流控制机制。但是,HTTP / 2在单个TCP连接中多路复用流,并且必须以不同的方式实现流控制。 #### HTTP / 2 HTTP / 2在单个TCP连接中多路复用数据流。结果,TCP连接级别的接收窗口不足以调节单个流的传递。HTTP / 2通过允许客户端和服务器实现自己的流控制,而不是依靠传输层来解决此问题。应用程序层传达可用的缓冲区空间,从而允许客户端和服务器在多路复用流的级别上设置接收窗口。在通过WINDOW_UPDATE框架进行初始连接后,可以修改或保持这种精细的流量控制。 由于此方法在应用程序层的级别上控制数据流,因此在调整接收窗口之前,流控制机制不必等待信号到达其最终目的地。中间节点可以使用流控制设置信息来确定自己的资源分配并相应地进行修改。这样,每个中间服务器都可以实现自己的自定义资源策略,从而提高连接效率。 在创建适当的资源策略时,流控制的这种灵活性可能是有利的。例如,客户端可以获取图像的第一次扫描,将其显示给用户,并允许用户预览图像,同时获取更多关键资源。客户端获取这些关键资源后,浏览器将恢复图像剩余部分的检索。因此,将流控制的实现推迟到客户端和服务器可以提高Web应用程序的感知性能。 在前面一节中提到的流控制和流优先级方面,HTTP / 2提供了更详细的控制级别,为进一步优化提供了可能。下一节将说明该协议特有的另一种方法,该方法可以通过类似的方式增强连接:使用服务器push预测资源请求。 ### 预测资源请求 在典型的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模式](https://developers.google.com/web/fundamentals/performance/prpl-pattern/)。要了解有关服务器推送的可能问题的更多信息,请参阅Jake Archibald的博客文章[HTTP / 2 push比我想象的要难](https://jakearchibald.com/2017/h2-push-tougher-than-i-thought/)。 ### 压缩 优化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](https://tools.ietf.org/html/draft-ietf-httpbis-header-compression-12)可以压缩此标头帧。该算法可以使用霍夫曼编码对标头元数据进行编码,从而大大减小其大小。此外,HPACK可以跟踪先前传送的元数据字段,并根据客户端和服务器之间共享的动态更改的索引进一步压缩它们。例如,接受以下两个请求: ![](https://img2018.cnblogs.com/blog/1814598/201910/1814598-20191016133943444-2027441739.png) ![](https://img2018.cnblogs.com/blog/1814598/201910/1814598-20191016133943607-950751973.png) 在这些请求的各种领域中,如method,scheme,host,accept,和user-agent,具有相同的值; 只有path字段使用不同的值。结果,在发送时Request #2,客户端可以使用HPACK仅发送重建这些公共字段和对该path字段进行新编码所需的索引值。结果头帧将如下所示: ![](https://img2018.cnblogs.com/blog/1814598/201910/1814598-20191016133943743-2003516825.png) ![](https://img2018.cnblogs.com/blog/1814598/201910/1814598-20191016133943879-1024780341.png) 使用HPACK和其他压缩方法,HTTP / 2提供了另一项功能,可以减少客户端-服务器延迟。 ### 结论 从此逐点分析中可以看出,HTTP / 2在许多方面与HTTP / 1.1有所不同,其中一些功能提供了更高级别的控制,可用于更好地优化Web应用程序性能,而其他功能则可以在先前的协议。现在,您已经对这两种协议之间的变化有了一个高级的了解,现在可以考虑HTTP / 2中的多路复用,流优先级,流控制,服务器推送和压缩等因素如何影响Web开发的不断变化的格局。 。 如果您希望看到HTTP / 1.1和HTTP / 2之间的性能比较,请查看此[Google演示](https://http2.golang.org/gophertiles),该演示比较了不同延迟的协议。请注意,当您在计算机上运行测试时,页面加载时间可能会因多种因素而异,例如带宽,测试时可用的客户端和服务器资源,等等。如果您想研究更详尽的测试结果,请参阅文章[HTTP / 2 –真实的性能测试和分析](https://css-tricks.com/http2-real-world-performance-test-analysis/)。最后,如果您想探索如何构建现代Web应用程序,则可以遵循我们的[《如何构建现代Web应用程序以使用Django和Ubuntu 18.04上的React来管理客户信息》](https://www.digitalocean.com/community/tutorials/how-to-build-a-modern-web-application-to-manage-customer-information-with-django-and-react-on-ubuntu-18-04)教程,或使用以下教程方法设置自己的HTTP / 2服务器[如何在Ubuntu 16.04上使用HTTP / 2支持设置Nginx](https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-with-http-2-support-on-ubuntu-16-04)。 原文:[HTTP/1.1 vs HTTP/2: What's the Difference?](https://www.digitalocean.com/community/tutorials/http-1-1-vs-http-2-what-s-the-difference) > 本文由博客一文多发平台 [OpenWrite](https://openwrite.cn?from=article_bottom) 发布!
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!