前言
HTTP2.0主要有三大特性:二进制协议、头部压缩、服务端推送(Server Push)、多路复用。本文从分析http1.x存在的问题入手,逐一介绍http2.0的优势。
Http1.x存在的问题
在HTTP1.0下,HTTP1.1非Keep-Alive模式下,每个请求都要新建一个TCP连接,完成之后立即断开连接,如果有新的请求,则要重新创建请求TCP连接。多次请求建立多次TCP会耗费大量时间,同时没有必要。
为了解决这个问题, HTTP 1.1 中提供了Keep-Alive
,允许一定时间(此时间在Nginx或Apache服务器配置上设定)内,同一域名多次请求数据,只建立一次HTTP请求,其他请求可复用TCP连接,以提高请求效率。
但是使用Keep-Alive
后仍然存在问题:
单个 TCP 连接在一个时刻只能处理一个请求(必须等上一个请求返回才能发起下一个请求,所以后面的请求会被前面请求的阻塞)。所以实际上我们只是节省了建立连接的时间,而获取数据的时间并没有减少。
http1.1的单个 TCP 连接只能同步发请求的原因:http1.1是基于文本的协议,请求中的不同部分(请求头、请求体)通过换行符进行分割。因此如果同一个TCP同时发多个请求会导致多个请求的数据混杂在一起,服务端无法正确解析请求。
Http2.0的特性
一、二进制协议
http1.x 是一个文本协议,而 http2.0 是一个彻彻底底的二进制协议,http2.0 的基本单位是帧。
HTTP2.0引入二进制数据帧和流的概念:
客户端发送请求时,请求会被分解为多个帧(Frame),同一个请求的帧的 流标识符(Stream Identifier) 相同。每个请求可以理解为一个包含多个帧的流。
帧的格式:
字段解释:
type的类型:
在二进制分帧层上,http2.0会将所有传输信息分割为帧,并对它们采用二进制格式的编码将其封装,新增的二进制分帧层同时也能够保证http的各种动词,方法,首部都不受影响,兼容上一代http标准。其中,http1.X中的首部信息header封装到Headers帧中,而request body将被封装到Data帧中。
二、多路复用 (Multiplexing) / 连接共享
有了新的分帧机制后,http/2 不再依赖多个TCP连接去实现多流并行:
每个数据流(请求或响应)都拆分成很多互不依赖的帧,因为具有标识字段(Stream id、flags)因此帧可以无序发送(即多个请求分解成帧可以通过一个TCP连接交错发送),最后当帧到达服务端之后,就可以根据 Stream Identifier 来重新组合得到完整的请求。
http 2.0 的TCP连接都是持久化的,而且客户端与服务器之间也只需要一个连接(每个域名一个连接)即可。此连接可以承载数十或数百个流的复用,多路复用意味着来自很多流的数据包能够混合在一起通过同样连接传输。当到达终点时,再根据不同帧首部的流标识符重新连接将不同的数据流进行组装。
http1.X和http2.0在传输数据时的区别:
三、头部压缩
客户端和服务器各自维护一张头部信息表,所有头部字段都会存入表中,生成一个索引号,发送过的头部字段此后只发送对应的索引号。
相同的头部信息不会通过请求发送,延用之前请求携带的头部信息。新增/修改的头部信息会被加入到HEAD中,两端渐进更新。
两端会共同维护一个head list,每次请求时都会进行检查。
该list包括:
- static (既定的头部信息)
- dynamic (自定义的头部信息)
四、服务端推送
例如我们加载index.html, 我们可能还需要index.js, index.css等文件。传统的请求只有当拿到index.html,解析html中对index.js/index.css的引入才会再请求资源加载,但是通过服务端推送,可以提前将资源推送给客户端,这样客户端要用到的时候直接调用即可,不用再发送请求。
当服务端需要主动推送某个资源时,便会发送一个 Frame Type 为 PUSH_PROMISE 的 Frame,里面带了 PUSH 需要新建的 Stream ID。意思是告诉客户端:接下来我要用这个 ID 向你发送东西,客户端准备好接着。客户端解析 Frame 时,发现它是一个 PUSH_PROMISE 类型,便会准备接收服务端要推送的流。
参考
- 一次 HTTP 请求就需要一次 TCP 连接吗?
- 推荐阅读:深入理解http2.0协议,看这篇就够了
- https://www.jianshu.com/p/ff8f0bd78942
- https://segmentfault.com/a/1190000011172823
- https://blog.csdn.net/weixin_33693070/article/details/88711831
- https://www.cnblogs.com/shangyueyue/p/11049984.html
- https://www.jianshu.com/p/1ad439279974
- https://blog.csdn.net/u010552788/article/details/80593955