# ❓简单讲解一下 http2 的多路复用
还是要介绍一下,http 多个请求发展史的。
多个 TCP 链接 -> keep-alive -> 管线化(pipe-line)-> 多路复用
# 多个 TCP 链接
最初的时候要想做多次请求,只能建立多个 TCP 链接来实现通信,一次请求完成之后就会关闭本次 TCP 链接,下次链接又要重新建立 TCP 链接,重复链接动作。 这回带来很大性能损耗。
# keep-alive
一定时间内(可以配置),同一域名多次请求数据,只建立一次 HTTP 请求,其他请求可复用每一次建立的连接通道,以达到提高请求效率的问题。
以往,浏览器判断响应数据是否接收完毕,是看连接是否关闭。在使用持久连接后,就不能这样了,这就要求服务器对持久连接的响应头部一定要返回 content-length
标识 body
的长度,供浏览器判断界限。有时,content-length
的方法并不是太准确,也可以使用 Transfer-Encoding: chunked
头部发送一串一串的数据,最后由长度为 0 的 chunked
标识结束。
但是还是存在问题
- 串行的文件传输
- 同域并行请求限制带来的阻塞(6~8)个
# 管线化(pipe-line)
可以克服同域并行请求限制带来的阻塞
,它是建立在持久连接之上,是把所有请求一并发给服务器,但是服务器需要按照顺序一个一个响应,而不是等到一个响应回来才能发下一个请求,这样就节省了很多请求到服务器的时间。不过,HTTP 管线化仍旧有阻塞的问题,若上一响应迟迟不回,后面的响应都会被阻塞到。
# 多路复用
代替原来的序列
和阻塞机制
。所有就是请求的都是通过一个 TCP
连接并发完成。因为在多路复用之前所有的传输是基于文本(所有的数据必须按顺序传输,比如需要传输:hello world
,只能从 h
到 d
一个一个的传输,不能并行传输,因为接收端并不知道这些字符的顺序,所以并行传输在 HTTP1.1
是不能实现的。)的。多路复用中是基于二进制数据帧的传输、消息、流,所以可以做到乱序的传输。多路复用对同一域名下所有请求都是基于流,所以不存在同域并行的阻塞。
# 总结
在 HTTP/2 中,有两个非常重要的概念,分别是帧(frame)和流(stream)。
帧 代表着最小的数据单位,每个帧会标识出该帧属于哪个流,流也就是多个帧组成的数据流。
HTTP2 采用二进制数据帧传输,取代了 HTTP1.x 的文本格式,二进制格式解析更高效。