先看看官网的描述
1 | HTTP/2 is a replacement for how HTTP is expressed “on the wire.” It is not a ground-up rewrite of the protocol; HTTP methods, status |
也就是说:
- HTTP/2是现行HTTP协议(HTTP/1.x)的替代,但它不是重写。HTTP/2 兼容HTTP/1.x的语义
- HTTP/2对性能有了很大的提升
可以看出HTTP/2关注的是缩减延迟、网络和服务器资源的利用。主要目的就是在一个连接上就可以搞定所有问题。那么HTTP/1.x 有哪些问题呢?
HTTP/1.X的问题#
队头阻塞
服务端收到多个管道请求后,需要按接收顺序逐个响应。如果恰好第一个请求特别慢,后续所有响应都会跟着被阻请求头冗余
HTTP/1 协议头部使用纯文本格式,没有任何压缩,且包含很多冗余信息(例如 Cookie、UserAgent 每次都会携带),所以一个页面的请求数越多,头部带来的额外开销就越大
- 没有优先级
资源是有优先级的。但HTTP/1 却一视同仁。高优先级的排在了一个低优先级资源之后
- 不支持多路复用
如果要实现并发,只能通过建立多个连接实现。
HTTP/2 简介#
二进制分帧#
HTTP2中二进制协议的基本单元叫 frame(帧),不同frame 有不同作用。 例如:
- SETTING 帧:建立连接时,向对方传达一些配置信息如是否开启 server push 功能、最大帧 size等等;
- HEADERS 帧:发送 http 的 request 或者response的头部;
- CONTINUATION 帧:headers 要跨越多个帧,用此来指示头部上一个 HEADERS;本质就是 HEADERS 帧,但是为了轻松处理,就用明确的类型来区分这种情况;
- DATA 帧:发送body数据用;
- USH_PROMISE 帧:用来告知对端初始化哪些数据,就是以上说到的 server push 功能
- WINDOW_UPDATE 帧:用来做流量控制
其中最基础的就是HEADERS帧
与 DATA帧
,分别对应http/1.x的请求头和请求头
帧结构#
1 |
|
length:24位,表示 Frame Payload的长度
type: 8位,表示帧的类型
R 一位,无用
Stream Identifier:无符号,31位,表示 stream id,用于区分所属的流;
Frame Payload : frame 携带的可变长数据,可为空;
多路复用的流#
在帧结构中可以看到 Stream Identifier
将每一个帧关联到流。那么流是什么呢?
流是一个独立的,双向的帧序列可以通过一个http2的连接在服务端与客户端之间不断的交换数据。
每个单独的http2连接都可以包含多个并发的流,这些流中交错的包含着来自两端的帧。流既可以被客户端/服务器端单方面的建立和使用,
也可以被双方共享,或者被任意一边关闭。在流里面,每一帧发送的顺序非常关键。接收方会按照收到帧的顺序来进行处理。
流的多路复用意味着在同一连接中来自各个流的数据包会被混合在一起。就像快递公司的运货车,所有的邮件都放在一辆车内,到了终点才会进行区分。
优先级#
每个流都包含一个优先级,它被用来告诉对端哪个流更重要。当资源有限的时候,服务器会根据优先级来选择应该先发送哪些流。
头压缩#
解决上文中,HTTP/1 协议头部使用纯文本格式,并且很多冗余信息。针对这些 进行压缩。
缓存推送#
当一个客户端请求资源X,而服务器知道它很可能也需要资源Z的情况下,服务器可以在客户端发送请求前,主动将资源Z推送给客户端。
这个功能帮助客户端将Z放进缓存以备将来之需。