多路复用
同个域名只需要占用一个 TCP 连接,消除了因多个 TCP 连接而带来的延时和内存消耗。
队头阻塞(Head-of-Line Blocking)
正如你所见的,浏览器客户端浪费了大量的时间等待资源返回。主要是因为HTTP/1无法通过单一的连接来进行并发的请求,所以浏览器通常情况下采用打开多个连接的方式来加速获取资源的进程。 奢侈的连接
然而使用打开多个连接来辅助加速的方式,从计算机网络的角度来看,每打开一个链接都是非常奢侈的。由于建立连接的花销非常大,目前的浏览器都会对HTTP/1.1的最大连接数进行限制,一般为6-8个。但是很多网站,会去请求80个乃至更多的资源,因此,这个限制也会导致很大的性能瓶颈。
二进制分帧
HTTP2引入了二进制分帧层,将普通的请求/响应,拆解为帧实现请求和响应的并发。 帧的结构 分为9字节的头部和指定长度的Payload
+-----------------------------------------------+
| Length (24) |
+---------------+---------------+---------------+
| Type (8) | Flags (8) |
+-+-------------+---------------+-------------------------------+
|R| Stream Identifier (31) |
+=+=============================================================+
| Frame Payload (0...) ...
+---------------------------------------------------------------+
分为10种帧
- HEADERS: 报头帧 (type=0x1),用来打开一个流或者携带一个首部块片段
- DATA: 数据帧 (type=0x0),装填主体信息,可以用一个或多个 DATA 帧来返回一个请求的响应主体
- PRIORITY: 优先级帧 (type=0x2),指定发送者建议的流优先级,可以在任何流状态下发送 PRIORITY 帧,包括空闲 (idle) 和关闭 (closed) 的流
- RST_STREAM: 流终止帧 (type=0x3),用来请求取消一个流,或者表示发生了一个错误,payload 带有一个 32 位无符号整数的错误码 (Error Codes),不能在处于空闲 (idle) 状态的流上发送 RST_STREAM 帧
- SETTINGS: 设置帧 (type=0x4),设置此 连接 的参数,作用于整个连接
- PUSH_PROMISE: 推送帧 (type=0x5),服务端推送,客户端可以返回一个 RST_STREAM 帧来选择拒绝推送的流
- PING: PING 帧 (type=0x6),判断一个空闲的连接是否仍然可用,也可以测量最小往返时间 (RTT)
- GOAWAY: GOWAY 帧 (type=0x7),用于发起关闭连接的请求,或者警示严重错误。GOAWAY 会停止接收新流,并且关闭连接前会处理完先前建立的流
- WINDOW_UPDATE: 窗口更新帧 (type=0x8),用于执行流量控制功能,可以作用在单独某个流上 (指定具体 Stream Identifier) 也可以作用整个连接 (Stream Identifier 为 0x0),只有 DATA 帧受流量控制影响。初始化流量窗口后,发送多少负载,流量窗口就减少多少,如果流量窗口不足就无法发送,WINDOW_UPDATE 帧可以增加流量窗口大小
- CONTINUATION: 延续帧 (type=0x9),用于继续传送首部块片段序列,见 首部的压缩与解压缩
HTTP2 请求创建连接发送 SETTINGS 帧初始化前还有一个 Magic 帧 (建立 HTTP/2 请求的前言)。 在 HTTP/2 中,要求两端都要发送一个连接前言(常量字符串),作为对所使用协议的最终确认,并确定 HTTP/2 连接的初始设置,客户端和服务端各自发送不同的连接前言。
|