白话http2的多路复用
Posted nodejs全栈开发
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了白话http2的多路复用相关的知识,希望对你有一定的参考价值。
题图 From Bing By Clm
上篇文章介绍了http1.1相对于http2的一些不足,本篇文章来聊一聊http2的一些优点,但是http2的优点比较多,并且需要结合源码展示,所以关于htt2的一些特点,我打算拆分成多篇文章,本篇文章只讨论http2实现的多路复用功能。
回顾http1.1协议,我们了解到,虽然http1.1实现了tcp的长连接,在一个tcp链接通道中,我们可以连续处理多个http请求响应,但是这个处理过程是半双工模式,也就是同一时刻只能处理一个request的请求或者响应,后面的request必须等到前面的请求响应之后才能进行。
浏览器为了更加快速的加载页面资源,于是针对同一域名设置了最大并发数,这样做能稍微加快速度,但是也带了一些问题,参看上一篇文章。
http2完全摒弃http1.1半双工通信的方式,实现了全双工通信,具体表现为:浏览器针对同一个域名的资源,只建立一个tcp连接通道,所有的针对这个域名的请求全部在这个通道中完成,并且引入了流的机制,这条通道可以同时处理多个request,这不同于http1.1的pepeline,http2的多路复用,对于request的响应并不会因为上一个request的响应未完成而阻塞,http2彻底解决了。
http2中在一个tcp通道中的所有http请求不分先后,不会阻塞,同样是一个页面中多个资源同时去请求,用http2来实现的话,过程如图:
这张图与上一篇文章中http1.1版本中的图是有区别的,可以看到这里http请求并不会因为前面的请求未响应而阻塞。
我们来通过几张图来演示一下http1.1到http1.1的pipeline在到http2的进化。
先看第一张图:
仔细观察上图,发现在http1.1版本中的一个tcp通道中,这是一个单通道,同一时刻只能处理一个http请求,并且必须按照顺序。
再看第二张图:
仔细观察这张图,虽然在一个tcp通道中实现了多个http并发,但是返回的时候是会阻塞的,谁先到达,谁先返回,顺序绝对不能乱,这就是http1.1pipeline的弊端。还有另一个pipeline的限制,只能是幂等请求(get、head等)才能应用pipeline,大部分浏览器默认是关闭pipeline的。
再看第三张图:
这张图中在一个tcp链接通道中,同时进行多个http请求和响应,仔细观察请求顺序和响应顺序无关,速度相对于上面两张图明显变快,并且页面中的资源请求都在一个tcp通道中完成,有效的避免了tcp竞速,慢启动等因素。
上面只是演示了http2的传输方式,那么他是如何实现的呢?
http1.1是明文协议,解析http1.1的明文是基于文本。http2.0的协议采用的是二进制格式。
http2为什么要采用二进制格式呢?
1、基于文本解析的话,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多。
2、二进制则只认0和1的组合,解析速度更快。
那么在不改动 HTTP/1.1 的语义、⽅法、状态码、URI 以及⾸部字段等等的情况下, HTTP/2 是如何过渡到http1.1呢?
关键之⼀就是在应⽤层(HTTP/2)和传输层(TCP or UDP)之间增加⼀个⼆进制分帧层。如图:
在⼆进制分帧层中, HTTP/2 会将所有传输的信息分割为更⼩的消息并封装在帧(frame)中,并对它们采⽤⼆进制格式的编码 ,其中 HTTP1.1的⾸部信息会被封装到 HEADER frame,⽽相应的 Request Body 则封装到 DATA frame ⾥⾯。如上图的HEADER frame和DATA frame分别对应http1.1的请求头和请求体。
对比如图:
并且,HTTP/2 通信都在⼀个tcp连接上完成,这个连接会同时处理多个http的request,http2给每个http的request都分配唯一的streamId,而每个request切割出来的fram都共用这个streamId,这样的话http2就可以基于这个streamid将切割的信息还原,http2通道中同时处理多个request的方式类似处理多个流,所以有些文章会指出http2实现了流方式传递信息。如图:
上图中每个大的蓝色方块代表一个http的request,每个request被切割为多个fream,并且被编号,我们用黄红绿三种颜色分别代表三个stream流,不同的颜色代表不同的streamid,http2接收到数据会根据其streamid自动还原数据,这样就实现了在一个TCP连接通道中的流式传输,多个request都会复用这个TCP通道,实现了高效的复用。
总结一下:上文我们简单介绍了http2的多路复用功能,简单来说有如下几个特点:
1、http2针对同一个域名只建立一个TCP链接,所有http请求都通过这个TCP链接来完成。
2、http2将每个request切割为更小的帧,有header帧和body帧,并且给同一个request的帧分配相同的streamId,模拟实现了流的传输。
欢迎大家关注、转发,如果你有更好的建议或者问题欢迎留言。
以上是关于白话http2的多路复用的主要内容,如果未能解决你的问题,请参考以下文章