HTTP2新特性

缘起

    其实切到http2已经很久很久了,只是笔者比较懒,一直没有将一些知识整理到blog上,最近疫情,突然想将一些笔记中的东西,整理一下到博客。

HTTP发展历经的核心特性说明

  • http1.0: 每一个http请求消耗一个tcp连接,必须等待第一个http request处理完成后,才能进行下一次请求;
  • http1.1: 引入keepalive特性,允许多个http request使用同一个tcp连接。但请求仍然是串行的,虽然引入了pipeline技术,允许了一次性发起多个request,但是在接收response的时候,也必须是串行和有序的,即第一个request的response必须第一被就收完成,才能继续处理下一个request的response,所以仍然存在对头阻塞问题;
  • http2:可以多个请求同时在一个TCP上发送;只维护一个tcp链接,就减少了tcp链接建立和断开的资源消耗。在http1.1中的使用资源的合并请求来减少tcp链接的优化就没有必要了。

接下来简单说明一下http2中新增的一些核心特性。

使用了二进制分帧

    http2.0在应用层和传输层之间新增了一个二进制分帧层,从而达到在不改变http语义、http方法、状态码、URI、首部字段等前提下,突破http1.1的一些性能限制,改变传输性能,降低延迟,提高性能。

在二进制分帧中,http2将数据分割成更小的消息和帧,并对他们采用二进制的形式进行编码,其中http1.1的头部会被封装到header帧中,request body会被封装到data帧中。http2的数据传输会在一个连接上传输完成,这个连接承载了任意数量的双向数据流。每个数据流已消息的形式发送,而消息可以是一个帧或者多个帧组成,这些帧是可以乱序发送的,然后再根据每个帧的首部的流标识信息进行重新组装。

  • 基本原理:
        http1.1直接使用字符形式的请求报文提交到tcp层进行处理,在应用层必须解析出来请求的header和body才能完成通信;
        在HTTP2中,应用层的数据是通过二进制帧来进行处理,将不同的请求拆成不同的stream进行处理,并使用stream ID进行标记,正式有了stream id来进行标记,才能确保不同类型的帧才能被有序的重组。
        例如,浏览器加载hello.png和hello.js两个资源,png的请求标记为stream 01,js的请求被标记为stream 02。两个请求的header和data帧分别被标记为header 01/02、data 01/02。浏览器将header01,data01,header02,data02四个帧会同时放到一条TCP连接中进行传输,在tcp层中,会进一步进行拆分,拆分成不同的序号的报文进行传输。因在传输的过程中各个分片的传输是无序的,这个tcp中会讲到,这里不过多阐明。在http1.1中,因为http的request处理,必须有序,所以具有首部阻塞的问题。http2中接收端会根据不同的stream id进行帧的重新组合,比如这里会将stream 01标识的帧组装在一起。将stream 02的帧组装在一起。所以,server端是不需要一定等到png或者js请求全部接收完成之后,再处理下一个,完全可以将先接收完成的数据帧进行组装,处理并返回。
    在这里插入图片描述
        http2中将传输的帧相互独立,互不影响,这种方式就允许了并行交错的发送请求,而不用关心,请求之间会相互影响。可以并行交错的发送响应,响应之间互不干扰,只使用一个连接就能并行发送多个请求和响应,完美解决http1.1中的首部阻塞问题。也就是说http1.1中”分拆域名"来进行并发请求的优化在http2.0中没有任何意义。

头部压缩

在这里插入图片描述
    如上图,http2.0中,在客户端和服务端同时使用了首部表来进行跟踪和存储header的键值对。对相同的请求,就不需要在重新发送,在通信过程中,基本不会改变的字段,如User-agent,content-Type等字段,只需要进行一次传输,相当于会进行一次cache。首部表,就相当于一个密码本一样,约定好"我想你了"代码为01,"我也想你了"代码为02。那跟女朋友千里传信的时候,只用发01就好啦。
    在这种情况下,如果对统一资源请求的轮询请求,那就完全可以不进行首部传输。如果首部有发生变化,已只需要发送变化的数据在HEADER帧中,新增或修改的首部帧会追加在首部表中。
在这里插入图片描述

多路复用

在这里插入图片描述
在这里插入图片描述

因为画图很难啊,原谅我只能盗图了。之所以堆了两个图,是因为http2的多路复用,上面的图更清楚一些。

    讲到http2的多路复用技术,就不得不提http1.1中的pipeline技术。http1.0中,每一个请求都必须消耗一个tcp连接,一个request发起,就会新建一个tcp连接,等到接收response完成之后,tcp连接就会香消玉殒。当然,下一个http请求也才能开始发起。所以,效率可想而知。
    http1.1中加入了pipeline技术,允许一次性的发送多个request请求,但是pipeline在接收response的时候,也必须是有序的接收,即第一个发送的request,对应的response也必须第一个进行接收,就算其他的response先到达,接收时也必须进行等待。这就是http1.1中对头阻塞了。
    http2中在一个tcp连接中请求被分帧独立无序传输,前面已经做了详细解说了。

请求优先级

    这也是为了解决连接无序发送所带来的问题而提出的。因为请求的无序发送,并行交错。那万一请求方就是需要先加载css资源,js.最后加载视频资源呢。要是css一直晚于视频资源,那页面没了样式,岂不是很尴尬。所以,在http2中的流中有了优先级的概念,所以在每一个请求流中都会带一个31bit的优先值,0表示优先级最高,2的31次方减一最低。客户端明确请求资源的优先级,服务端可以根据这个优先级作为交互数据的依据。比如 css>js>png>mp4,服务端按这个顺序返回就会更加有利于利用底层的连接,提高用户体验。当然这个也不是绝对的,绝对等待会造成对头阻塞的。
关于优先级的一些实现原理可以参考:HTTP/2流的优先级

服务器推送

    HTTP 2.0新增加服务器提示,可以先于客户端检测到将要请求的资源,提前通知客户端,服务器不发送所有资源的实体,只发送资源的URL,客户端接到提示后会进行验证缓存,如果真需要这些资源,则正式发起请求(服务器主动更新静态资源)

本文只是http2知识的冰山一角。详细的还是需要去细品RFC7540

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值