HTTP2.0知识点有哪些

发布时间:2022-01-06 14:40:38 作者:iii
来源:亿速云 阅读:151

本篇内容主要讲解“HTTP2.0知识点有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“HTTP2.0知识点有哪些”吧!

1.二进制分帧

HTTP2.0的根本改进还是新增的二进制分帧层,不同于HTTP1.X使用换行符分割纯文本,二进制分帧层更加简洁,处理起来也更加高效。这里所谓的层,指的是位于套接字接口与应用可见的高层HTTP API间的一个新机制:HTTP语义,包括各种动词、方法、首部,都不受影响,不同的是传输它们的编码方式变了。HTTP 1.X以换行符作为纯文本的分隔符,而HTTP 2.0将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码。示例如下:

由上图可知,在HTTP1.1传输数据时,首部和数据是一块发送的,每次传输都是需要带有首部信息;在HTTP2.0中,首部信息被分为一个独立的帧进行发送,数据帧在在首部帧发送后,再进行发送,而且采用首部压缩后,每次传输只需要发送改动的部分即可,极大提高了数据发送的效率。

1.1.分帧首部

在建立HTTP2.0连接之后,客户端与服务器会通过交换帧进行通信,帧是HTTP2.0协议的最小单位。所有的帧都拥有一个8字节的首部,具体格式如下:

  0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | R |     Length (14)           |   Type (8)    |   Flags (8)   |
 +-+-+-----------+---------------+-------------------------------+
 |R|                 Stream Identifier (31)                      |
 +=+=============================================================+
 |                   Frame Payload (0...)                      ...
 +---------------------------------------------------------------+

通过这个共享的8字节首部,可以很快确定帧的类型、标志和长度,而且每一帧的长度也是事先定义好的,解析器也可以迅速的找到下一帧的开始,并进行解析,这对于HTTP1.1X来说也是一个很大的提升。

1.2.帧类型

不管是在连接管理或单独的流中,每种帧都为了特定的目的而服务。在HTTP2.0中,共定义了以下10种帧类型:

注:服务器可以利用GOWAY类型的帧告诉客户端要处理的最后一个流ID,从而消除一些请求竞争,而且浏览器也可以据此智能地重试或取消“悬着的”请求。这也是保证复用连接安全的一个重要和必要的功能。

HTTP2.0性能增强的核心,全在于新增的二进制分帧层,它定义了如何封装HTTP消息并在客户端与服务器之间传输。由于在HTTP2.0中使用了新的组帧方式,这样一来,客户端和服务器为了相互理解,必须都使用新的二进制编码机制,所以HTTP1.x客户端无法理解只支持HTTP2.0的服务器,反之亦然。但这并不影响我们使用HTTP2.0,现有的应用不用关注这些变化,因为客户端和服务器会替它们完成必要的分帧工作。

1.3.流、消息和帧

新的二进制分帧机制改变了客户端与服务器之间交互数据的方式,为了更好的理解HTTP2.0中这一核心变化,下面介绍流、消息、帧这三个概念及区别:

所有HTTP2.0通信都在一个TCP连接上完成,这个连接可以承载任意数量的双向数据流。相应的,每个数据流以消息的形式发送,而消息由一个或多个帧组成,这些帧可以乱序发送,然后根据每个帧首部的流标识符重新组装。帧是HTTP2.0中的最小通信单位,不同类型的帧有特殊的作用。

2.多路复用

2.1.队列传输与多路复用

在HTTP1.x中,如果客户端想发送多个并行的请求以及改进性能,那么必须使用多个TCP连接,而且存在队首阻塞问题,严重影响数据的传输效率。在HTTP2.0中,二进制分帧机制突破了这些限制,实现了多向请求和响应,客户端和服务器可以把HTTP消息分解为互不依赖的帧,然后乱序发送,然后在接收端重新组装,这样就完成了消息的传输。示例如下:

由上图可知,在同一个连接中,有三个流在同时传输,有两个是从服务端发给客户端的,也有一个是从客户端发送到服务端,这就大大的提高了连接的利用率。
这个新的机制是革命性的,会在整个WEB技术栈中引发一系列连锁反应,从而带来巨大的性能提升,因为:

HTTP2.0的二进制分帧机制解决了HTTP1.X中存在的队首阻塞问题,也消除了并行处理和发送请求及响应时对多个连接的依赖。这样,就会使应用更快、开发更简单、部署成本更低,也会减少客户端和服务器的CPU及内存占用。

2.2.每个来源一个连接

在可以实现连接的多路复用后,HTTP2.0不再依赖多个TCP连接去实现多流并行了。现在,多个数据流都拆分成很多帧,而这些帧可以交错,还可以分别优先级。于是,所有的 HTTP2.0连接都是持久化的,而且客户端与服务器之间也只需要一个连接即可。每个来源一个连接显著减少了相关的资源占用:连接路径上的套接字管理工作少了,内存占用少了,连接吞吐量大了。所以,很多层面上都有不小的提高:

大多数HTTP连接的时间都很短,而且是突发性的,但TCP只在长时间连接传输大块数据时效率才高。HTTP2.0通过让所有数据流共用同一个连接,可以更有效地使用TCP连接。HTTP2.0不仅能够减少网络延迟,还有助于提高吞吐量和降低运营成本。
注:任何事物都有其两面性,每个来源一个连接当然也会带来一些问题:

虽然有上述问题影响HTTP2.0的性能,但实验表明一个TCP连接仍然是目前最佳的策略:压缩和优先级排定带来的性能提升,已经超过了队首阻塞造成的负面效应。与所有其他的性能优化一样,去掉一个性能瓶颈,又会带来新的瓶颈。对HTTP2.0而言,TCP很可能就是下一个瓶颈。这也是服务器端TCP配置对HTTP2.0至关重要的一个原因。

3.请求优先级

在HTTP消息被分解为很多独立的帧之后,就可以通过优化这些帧的交错和传输顺序,可以让最紧要的帧优先发送,以确保关键任务的快速展开。那么如何定义这些帧的发送顺序就是一个难题,为方便起见,在HTTP / 2标准允许每个流具有相关联的权重和依赖性:

通过流依赖和权重,客户端可以构建一个“优先级树”(如下图所示),将这个树发送到服务端,表达客户端愿意以怎样的方式接收响应;服务端在接收到该“优先级树”后,可以根据这个信息,通过协调相关服务器资源返回响应,如CPU、存储器、网络等资源,优先处理高优先级的流。并且一旦响应数据是可用的,服务端将分配更多的带宽以确保高优先级的快速响应。

HTTP 2.0内的一个流只能设置一个唯一的流依赖,被依赖流就是当前流的父节点流,如果省略了流依赖的声明,则默认依赖于“根流”。声明一个流的依赖性表明,如果可能的话,父流应先于子流进行资源分配和响应,例如请处理和响应C前交付响应D。
具有相同的父流的同级流应该按照其权重比例分配服务器资源。例如,如果流A具优先级重量为12,他的同级兄弟流B的权重为4,那么确定二者应分配的资源比例为:

由上可知,如A流得到四分之三可用资源分配的话,B流应得到可利用的资源的四分之一。为了更好的理解优先级机制,下面从左到右依次介绍上图的优先级重组情况:

从上述示例可知,流依赖和权重的组合提供了一个表达资源优先次序的方式,这可以为不同的资源定义优先级,可以更好的提高性能。HTTP/2协议也允许客户端在任何时间点更新优先级信息,优先级信息可以像它们被创建一样使用报头帧或者使用优先级帧来明确指定或者改变。有了这个优先级标识,客户端和服务器就可以在处理不同的流时采取不同的策略,以最优的方式发送流、消息和帧。优先级的目的是允许终端表达它如何让对等端管理并发流时分配资源。更重要的是,在发送容量有限时优先级能用来选择流来传输帧。提供优先级信息是可选的,没有明确指定时使用默认值。
流依赖和权重表达一个传输偏好,而不是一个要求,因此不保证一个特定的处理或传输顺序。也就是说,客户端不能强制服务器以流优先级的优先级来处理特定顺序的流。在选择HTTP2.0服务器时,需要考虑以下几个问题:

如果服务器不理睬所有优先值,那么可能会导致应用响应变慢:浏览器明明在等关键的CSS和JavaScript,服务器却在发送图片,从而造成渲染阻塞。然而,严格按照规定的优先级次序也可能带来次优的结果,因为这或许会再次引入队首阻塞问题,即某个高优先级的慢请求会不必要地阻塞其他资源的交付。
所以,服务器可以并且应该交错发送不同优先级别的帧,只要可能,高优先级流都应该优先传输,不过为了更高效地利用底层连接,不同优先级的混合也是必须的。因此优先级的表达仅仅是一个建议。

4.流量控制

流量控制的定义是用来保护端点在资源约束条件下的操作。流量控制解决的情况是接收端在一个流上处理数据的同时同样想继续处理同个连接上的其他流。在同一个TCP连接上传输多个数据流,就意味着要共享带宽。标定数据流的优先级有助于按序交付,但只有优先级还不足以确定多个数据流或多个连接间的资源分配,为解决这个问题,HTTP2.0为数据流和连接的流量控制提供了一个简单的机制:

HTTP/2只标准化WINDOW_UPDATE帧格式。HTTP2.0标准没有规定任何特定的算法、值,或者什么时候发送WINDOW_UPDATE帧,因此实现可以选择自己的算法以匹配自己的应用场景,从而求得最佳性能。
流量控制方案等确保同一连接上的流相互之间不会造成破坏性的干扰。流量控制在单个流及整个连接过程中使用,HTTP/2 通过使用WINDOW_UPDATE帧类型来提供流量控制。上面的机制和TCP流量控制是一样的思路,然而仅凭TCP流量控制是不能对一条HTTP2.0连接内的多个流实行差异化策略,所以专门有了HTTP2.0流量控制机制的出现。

5.服务器推送

5.1.服务器端推送

HTTP2.0新增了一个强大的功能,就是服务器可以对一个客户端请求发送多个响应。换句话说,出了最初请求的相应外,服务器还可以额外向用户端推送资源,而无需客户端明确地请求。示例如下:

这样一个机制需要解决的问题是什么呢?我们知道,通常一个web应用往往包含数十个资源,客户端需要分析服务器提供的文档才能逐个找到它们。那么为什么不让服务器提前就把这些资源推送给客户端,从而减少额外的延时呢?服务器已经知道客户端下一步要请求什么资源了,这时候服务器端推荐就可以大展拳脚了。事实上,网页上嵌入的CSS及JS,或通过URI嵌入的其他资源,也可以算是服务器端推送。把资源直接插入到文档中,就是把资源直接推送给客户端,而无需客户端主动请求。在HTTP2.0中,唯一的不同就是可以把这个过程从应用中拿出来,放到HTTP协议本身来实现,而且带来了如下好处:

有了服务器推送后,HTTP1.X时代的插入或嵌入资源的做法就可以退出历史舞台了。唯一有必要采用嵌入资源方式的情况就是该资源只供一个页面使用,而且编码代价不大,除此之外,其他所有的场景都应该使用服务器端推送。

注:所有服务器推送流都由PUSH_PROMISE发端,它除了对原始请求的响应之外,服务器向客户端发出的有意推送所述资源的信号。PUSH_PROMISE帧中只包含有要约资源的HTTP首部。

客户端在接收到PUSH_PROMISE帧之后,可以视自身需求选择接收或拒绝这个流。服务端推送也有一些限制:

因为推送的响应是有效地逐跳,中介端接从服务端接收到推送响应的可以选择不转发这些到客户端。也就是说,如何使用推送响应取决于这些中介端。相等的,中介可能选择不推送的额外的响应给客户端,不需要服务端进行任何操作。服务端只能推送可以被缓存的响应;被承诺的请求必须是安全的,而且绝对不能包含一个请求主体。

5.2.如何实现服务器端推送

服务器推送为优化应用的资源交付提供了很多可能,然而,服务器到底该如何确定哪些资源可以或应该推送呢?HTTP2.0并没有给出详尽的规定,那么就有可能出现多种策略,每种策略可能会考虑一种应用或服务器使用场景。

上面只是几个可能的策略,当然也有很多其他的实现方式,可能是手工调用低级的API,也可能是一种全自动的实现。总之,服务器推送领域将会出现很多有意思的创新。推送的资源将直接进入客户端缓存,就像客户端请求了一样,不存在客户端API或JS回调方法等通知机制,可以用于确定资源何时到达,整个过程对运行在浏览器中的web应用来说好像根本不存在。

虽然现在还不知道如何确定哪些资源可以或应该推送,但是如何发起推送的机制已经建立,由服务端先发起推送请求,客户端再进行推送响应。具体如下:

Push Requests

服务端推送语义上等同于服务端响应一个请求;然而,这种情况下请求也是由服务端发送的,作为一个PUSH_PROMISE帧。PUSH_PROMISE包含了一个报头区块,含有完整的服务端属性请求报头字段。推送的响应总是与客户端的一个明确的请求相关。服务端在这个明确的请求流上发送PUSH_PROMISE帧。PUSH_PROMISE帧一般包含被承诺的流标识符,从可用的服务端流标识符中选择。服务端应当在发送任何被承诺的响应之前发送一个PUSH_PROMISE帧。这避免了客户端在收到任何PUSH_PROMISE帧前发出请求而出现的竞赛。PUSH_PROMISE可以由服务端在任意由客户端打开的流上发送。

Push Responses

发送PUSH_PROMISE帧后,服务端可以开始接收被推送进来的响应作为一个由服务端发起的使用被承诺流标识的流的响应。一旦客户端接收到PUSH_PROMISE帧并且选择接受推送的响应,客户端不应该对被承诺的响应发起请求,直到被承诺的流被关闭为止。如果客户端以任何理由决定不希望接受服务端推送的响应,或者服务端花费太长时间才开始发送承诺的响应,客户端可以发送一个RST_STREAM帧,使用CANCEL或者REFUSED_STREAM码来关联被推送的流标识符。

6.首部压缩

HTTP的每一次通信都会携带一组首部,用于描述传输的资源及其属性。在HTTP1.X中,这些元数据是以纯文本形式发送的,通常会给每个请求增加500-800字节的负荷。如果算上COOKIE,增加的负荷会达到上千字节,为了减少这些开销并提升性能,HTTP2.0会压缩首部元数据:

于是,HTTP2.0连接的两端都知道已经发送了哪些首部,这些首部的值是什么,从而可以针对之前的数据只编码发送这些差异数据。在通信期间几乎不会改变的键值对只需发送一次即可,这样就大大提高了数据的载荷。示例如下:

HTTP/1 的状态行信息(Method、Path、Status 等),在 HTTP/2 中被拆成键值对放入头部(冒号开头的那些),同样可以享受到字典和哈夫曼压缩。另外,HTTP/2 中所有头部名称必须小写。
头部压缩需要客户端和服务器端做好以下工作:

静态字典的作用有两个:

同时,浏览器可以告知服务端,将 cookie: xxxxxxx 添加到动态字典中,这样后续整个键值对就可以使用一个字符表示了。类似的,服务端也可以更新对方的动态字典。需要注意的是,动态字典跟具体连接上下文有关,需要为每个 HTTP2.0 连接维护不同的字典。使用字典可以极大地提升压缩效果,其中静态字典在首次请求中就可以使用。对于静态、动态字典中不存在的内容,还可以使用哈夫曼编码来减小体积。HTTP2.0 使用了一份静态哈夫曼码表,也需要内置在客户端和服务端之中。哈夫曼编码的核心理念就是使用最少的位数表示最多的信息,HTTP2.0中这份哈夫曼编码表是根据一个大样本的HTTP报头的统计数据生成,经常出现的字符会用较短的二进制数标识,出现频率较低的字符用较长的二进制数标识,这样就保证了综合来看报头信息占用了较少的空间,进一步压缩了报头信息。

在服务端接收到压缩过的报头信息后,会先进行哈夫曼编码解码,得到报首信息后,再结合维护的静态字典和动态字典信息得出完整的报首信息,随后进行请求的处理和响应。在需要更新动态字典信息时,对字典进行更新。

HTTP2.0压缩算法:SPDY早期版本使用zlib和自定义的字典压缩所有的HTTP首部,可以减少85%-88%的首部开销,从而显著减少加载页面的时间。然而,在2012年夏天,出现了针对TLS和SPDY压缩算法的CRIME安全攻击,于是,zlib算法被撤销,取而代之的是前面介绍的新索引表算法。该算法没有类似的安全问题,但可以实现相差无几的性能提升。

7.HTTP2.0升级与发现

向HTTP2.0的迁移不可能瞬间完成,无论服务器端还是客户端都需要进行必要的更新升级才能使用。好消息是,大多数现代浏览器都内置有高效的后台升级机制,对大多数既有用户来说,这些浏览器可以很快的支持HTTP2.0,不会带来很大困扰。然而,服务器端和中间设备的升级、更新就不是那么容易,是一个长期的过程,而且很费力、费钱。

HTTP1.X至少还会存续十年以上,大多数服务器和客户端在此期间必须同时支持1.x和2.0标准。于是,支持HTTP2.0的客户端在发起新请求之前,必须能发现服务器及中间设备是否支持HTTP2.0协议。有以下三种情况:

HTTPS协商过程中有一个环节会使用ALPN发现和协商HTTP2.0支持情况。有 ALPN 的情况下 TLS 握手信息中包含了客户端支持的协议列表,服务端直接选择 HTTP2,所有协商在握手阶段一次完成,无需额外的报文。
注:应用层协议谈判(ALPN)是一个TLS扩展,支持在TLS握手过程中进行协议协商,从而省去通过HTTP的Upgrade机制所需的额外往返延迟。过程如下:

通过非加密信道建立HTTP2.0连接需要多做一些工作,因为HTTP1.0和HTTP2.0都使用80端口,又没有服务器是否支持HTTP2.0的其他任何信息,此时客户端只能使用HTTP upgrade 机制通过协商确定适当的协议:

GET /default.htm HTTP/1.1
Host: server.example.com
Connection: Upgrade, HTTP2-Settings
Upgrade: h3c
HTTP2-Settings: <base64url encoding of HTTP/2 SETTINGS payload>

不支持HTTP/2的服务端对请求返回一个不包含升级的报头字段的响应:

HTTP/1.1 200 OK
Content-Length: 243
Content-Type: text/html
...

支持HTTP/2的服务端可以返回一个101(转换协议)响应来接受升级请求:

HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: h3c
...

在101空内容响应终止后,服务端可以开始发送HTTP/2帧。这些帧必须包含一个发起升级的请求的响应。第一个被服务端发送的HTTP/2帧是一个设置(SETTINGS)帧。在收到101响应后,客户端发送一个包含设置(SETTINGS)帧的连接序言。

使用这种Upgrade流,如果服务器不支持HTTP2.0,就立即返回HTTP1.1响应。否则,服务器就会以HTTP1.1格式返回101 switching protocols响应,然后立即切换到HTTP2.0并使用新的二进制分帧协议返回响应。无论哪种情况,都不需要额外往返。

最后,如果客户端因为自己保存有或通过其他手段(如dns记录,手工配置)获得了HTTP2.0的支持信息,也可以直接发送HTTP2.0分帧,而不必依赖Upgrade机制。

8.HTTP2.0数据传输示例

发起新流

在发送应用数据之前,必须创建一个新流并随之发送相应的元数据,比如优先级、HTTP首部等。HTTP2.0协议规定客户端和服务器都可以发起流,因此有两种可能:

到此,相信大家对“HTTP2.0知识点有哪些”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

推荐阅读:
  1. http2.0反向代理遇到的坑
  2. 非加密http2.0

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

http

上一篇:怎么快速部署国人开源的Java博客系统Tale

下一篇:linux的数据一致性和io类型怎么理解

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》