04 网络面经:HTTP 2.0的这些新特性,是时候了解一下了
面试中关于HTTP 2.0的面试题并不多,但基于HTTP 2.0的应用已经很多了,比如谷歌的gRPC框架就是基于HTTP 2.0来提升效率的。同时,HTTP 1.0中的存在的很多缺陷也都在HTTP 2.0中得到了解决。
所以,如果你在面试中脱颖而出,同时,在实践中更好的理解类似gRPC这类框架的实现,了解HTTP 2.0还是非常必要的。而且HTTP 2.0也在很多场景下逐步替代HTTP 1.0。
HTTP 1.0存在的问题
了解过HTTP 1.0的协议实现之后,会发现它存在不少问题。
问题一:TCP连接数限制。为了避免网络拥堵,占用过多的CPU和内存。因此,不同的浏览器会限制TCP连接的数量。
问题二:队头阻塞问题。队头阻塞(Head Of Line Blocking),每个TCP同时只能处理一个HTTP请求,浏览器遵循FIFO原则,如果上一个没返回后续请求会被阻塞。
虽然提出了管道化(Pipelining)方案,但依旧存在诸多问题。比如,第一个响应慢还是会阻塞后续响应;服务器为了按序返回需要缓存多个响应,占用更多资源;浏览器中途断连重试服务器可能得重新处理多个请求;还有必须客户端 - 代理 - 服务器都支持管线化。
问题三:Header内容过多,每次都需重复发送,没有相应的压缩传输优化方案;
问题四:为了减少请求数,需做文件合并等优化工作,但同时会增加单个请求的延迟;
问题五:明文传输不安全;
HTTP 2.0的出现
针对HTTP 1.0的问题,RFC 7540定义了HTTP 2.0的协议规范和细节。HTTP 2.0的实现是基于SPDY协议的一些标准来实现的。
HTTP 2.0提供了:二进制分帧、首部压缩、多路复用、请求优先级、服务器推送等优化。
HTTP 2.0是在SPDY(An experimental protocol for a faster web, The Chromium Projects)基础上形成的下一代互联网通信协议。HTTP/2 的目的是通过支持请求与响应的多路复用来较少延迟,通过压缩HTTPS首部字段将协议开销降低,同时增加请求优先级和服务器端推送的支持。
什么是SPDY协议
SPDY是Google开发的基于TCP协议的应用层协议。目标是优化HTTP协议的性能,通过压缩、多路复用和优先级等技术,缩短网页的加载时间并提高安全性。协议的核心思想是尽量减少TCP连接数。SPDY并不是一种用于替代HTTP的协议,而是对HTTP协议的增强。
互联网工程任务组(IETF)对谷歌提出的SPDY协议进行了标准化,于2015年5推出了类似于SPDY协议的HTTP 2.0协议标准(简称HTTP/2)。谷歌因此宣布放弃对SPDY协议的支持,转而支持HTTP/2。
下面详细了解一下HTTP 2.0提供的新特性。
二进制分帧层 (Binary Framing Layer)
在保证HTTP1.x不受到影响的情况下,HTTP 2.0是怎样突破HTTP 1.1的性能限制,改进传输性能,实现低延迟高吞吐量的呢?关键之一就是在应用层(HTTP)和传输层(TCP)之间增加一个二进制分帧层。二进制分帧层,是HTTP 2.0性能增强的核心。
HTTP 1.1在应用层以纯文本的形式进行通信,而HTTP 2.0将所有的传输信息分割为更小的消息和帧,并对它们采用二进制格式编码。同时,客户端和服务端都需要引入新的二进制编码和解码的机制。如下图所示,HTTP 2.0并没有改变HTTP 1.x的语义,只是在应用层使用二进制分帧方式传输。
HTTP/2协议
关于二进制分帧,有三个相关概念:帧、消息和流。
帧:HTTP 2.0通信的最小单位,所有帧都共享一个8字节的首部,其中包含帧的长度、类型、标志、还有一个保留位,并且至少有标识出当前帧所属的流的标识符,帧承载着特定类型的数据,如HTTP首部、负荷等等。
+-----------------------------------------------+
| Length (24) |
+---------------+---------------+---------------+
| Type (8) | Flags (8) |
+-+-------------+---------------+-------------------------------+
|R| Stream Identifier (31) |
+=+=============================================================+
| Frame Payload (0...) ...
+---------------------------------------------------------------+
基于帧,以二进制传输代替原本的明文传输,原本的报文消息被划分为更小的数据帧:
HTTP/2协议
在二进制分帧层上,HTTP 2.0会将所有传输的信息分为更小的消息和帧,并采用二进制格式编码,其中HTTP 1.1的首部信息会被封装到Headers帧,而Request Body则封装到Data帧。
消息:比帧大的通讯单位,是指逻辑上的HTTP消息(请求/响应),一系列数据帧组成了一个完整的消息。比如一系列DATA帧和一个HEADERS帧组成了请求消息。由一个或多个帧组成。
流:比消息大的通讯单位,是TCP连接中的一个虚拟通道,可以承载双向的消息。每个流都有一个唯一的整数标识符。
为防止两端流ID冲突,客户端发起的流具有奇数ID,服务器端发起的流具有偶数ID。所有HTTP 2. 0通信都在一个TCP连接上完成, 这个连接可以承载任意数量的双向数据流Stream。相应地,每个数据流以消息的形式发送,而消息由一或多个帧组成,这些帧可以乱序发送,然后根据每个帧首部的流标识符重新组装。
HTTP/2协议
二进制分帧层保留了HTTP的语义不受影响,包括首部、方法等,在应用层来看,和HTTP 1.x没有差别。同时,所有同主机的通信能够在一个TCP连接上完成。
● 单连接多资源的方式,减少服务端的链接压力,内存占用更少,连接吞吐量更大;
● 由于TCP连接的减少而使网络拥塞状况得以改善,同时慢启动时间的减少,使拥塞和丢包恢复速度更快。
多路复用 (MultiPlexing)
多路复用允许同时通过一个TCP连接发起多重的请求-响应消息。消息由帧构成,每帧数据上都标识属于哪个流(StreamID),对方接收时根据流ID拼接每个流所有帧的数据,组成一块完整的数据。这就是HTTP/2的多路复用。
流的概念实现了单连接上多请求-响应并行,解决了“队头阻塞(Head of line blocking)”的问题,减少了TCP连接数量和TCP连接慢启动的问题。所以HTTP/2对于同一域名只需要创建一个连接,而不是像HTTP/1那样需要创建6~8个连接。
需要注意的是不同流的数据可以交叉发送,但同一个流的数据只能顺序发送。
服务端推送 (Server Push)
客户端发送一个请求,服务器根据客户端的请求,提前返回多个响应,这样客户端就不用发起后续请求。也就是说,在HTTP/2中,服务器可以对客户端的一个请求发送多个响应。服务器向客户端推送资源无需客户端明确的请求。
如下图,客户端请求Stream 1(/page.html),服务端在返回Stream 1消息的同时推送了Stream 2(/script.js)和Stream 4(/style.css):
HTTP/2协议
如果一个请求是由主页发送的,服务器可能会响应主页内容、logo以及样式表,因为它知道客户端会用到这些。这样不但减轻了数据传送冗余步骤,也加快了页面响应的速度,提高了用户体验。
服务端推送主要是针对资源内联做出的优化,相较于HTTP/1.1资源内联的优势:
● 客户端可以缓存推送的资源;
● 客户端可以拒收推送过来的资源;
● 推送资源可以由不同页面共享;
● 服务器可以按照优先级推送资源;
推送的缺点:所有推送的资源都必须遵守同源策略。换句话说,服务器不能随便将第三方资源推送给客户端,而必须是经过双方的确认才行。
Header 压缩 (HPACK)
HTTP/1.1并不支持HTTP首部压缩,为此SPDY和HTTP/2应运而生, SPDY使用的是通用的算法,而HTTP/2则使用了专门为首部压缩而设计的算法(HPACK算法)。
HTTP/2协议
HTTP协议是无状态的,每次请求都必须附上所有信息(描述资源属性),重传数据达到几百甚至几千字节。所以,请求头字段很多都是重复的,比如Cookie,一样的内容每次请求都必须附带,会浪费很多带宽,也影响速度。
其实,对于相同的头部,只需发送一次即可。HTTP/2对这一点做了优化,引入了头信息压缩机制。一方面,头信息使用gzip或compress压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,产生一个索引号,之后就不发送同样字段了,只需发送索引号。
请求优先级
把HTTP消息分为很多独立帧之后,就可以通过优化这些帧的交错和传输顺序进一步优化性能。HTTP/2中每个Stream都可以设置依赖 (Dependency) 和权重,可以按依赖树分配优先级,解决了关键请求被阻塞的问题。
应用层的重置连接
对于HTTP/1来说,是通过设置tcp segment中的reset flag来通知对端关闭连接的。这种方式会直接断开连接,下次再发请求就必须重新建立连接。HTTP/2引入 RST_STREAM类型的 frame,可以在不断开连接的前提下取消某个request的stream,表现更好。
流量控制
TCP协议是通过sliding window算法来做流量控制的。发送方有一个sending window,接收方有一个receive window。HTTP/2的flow control类似receive window,数据接收方通知对方字节的flow window大小,表明还能接收的数据量。只有Data类型的frame才有flow control功能。
通过上述方式,可以限制另一端发送数据。对于每个流来说,两端都必须告诉对方自己还有足够的空间来处理新的数据,而在该窗口被扩大前,另一端只被允许发送这么多数据。
小结
每一个新的协议的应用普及都需要一个过程,HTTP/2也不例外。还好的是,它是上层协议,而且只是在HTTP/1和TCP之间添加了一层,逐步被使用必然是趋势。在了解了HTTP/2的这些新特性之后,或许你已经明白,为什么越来越多的浏览器、中间件开始采用HTTP/2了。因为,它的确非常高效,值得你学习并运用。
文章转载自公众号:程序员新视界