HTTP 2.0是在SPDY(An experimental protocol for a faster web, The Chromium Projects)基础上形成的下一代互联网通信协议。HTTP/2 的目的是通过支持请求与响应的多路复用来较少延迟,通过压缩HTTPS首部字段将协议开销降低,同时增加请求优先级和服务器端推送的支持。
本文目的是学习HTTP 2.0的原理并研究其通信的详细细节。大部分知识点源于《Web性能权威指南》。
1. 二进制分帧层
二进制分帧层,是HTTP 2.0性能增强的核心。
HTTP 1.x在应用层以纯文本的形式进行通信,而HTTP 2.0将所有的传输信息分割为更小的消息和帧,并对它们采用二进制格式编码。这样,客户端和服务端都需要引入新的二进制编码和解码的机制。
如下图所示,HTTP 2.0并没有改变HTTP 1.x的语义,只是在应用层使用二进制分帧方式传输。
因此,也引入了新的通信单位:
1.1 帧(frame)
HTTP 2.0通信的最小单位,包括帧首部、流标识符、优先值和帧净荷等。
其中,帧类型又可以分为:
- DATA:用于传输HTTP消息体;
- HEADERS:用于传输首部字段;
- SETTINGS:用于约定客户端和服务端的配置数据。比如设置初识的双向流量控制窗口大小;
- WINDOW_UPDATE:用于调整个别流或个别连接的流量
- PRIORITY: 用于指定或重新指定引用资源的优先级。
- RST_STREAM: 用于通知流的非正常终止。
- PUSH_ PROMISE: 服务端推送许可。
- PING: 用于计算往返时间,执行“ 活性” 检活。
- GOAWAY: 用于通知对端停止在当前连接中创建流。
标志位用于不同的帧类型定义特定的消息标志。比如DATA帧就可以使用End Stream: true
表示该条消息通信完毕。流标识位表示帧所属的流ID。优先值用于HEADERS帧,表示请求优先级。R表示保留位。
下面是Wireshark抓包的一个DATA帧:
1.2 消息(message)
消息是指逻辑上的HTTP消息(请求/响应)。一系列数据帧组成了一个完整的消息。比如一系列DATA帧和一个HEADERS帧组成了请求消息。
1.3 流(stream)
流是连接中的一个虚拟信道,可以承载双向消息传输。每个流有唯一整数标识符。为了防止两端流ID冲突,客户端发起的流具有奇数ID,服务器端发起的流具有偶数ID。
所有HTTP 2. 0 通信都在一个TCP连接上完成, 这个连接可以承载任意数量的双向数据流Stream。 相应地, 每个数据流以 消息的形式发送, 而消息由一 或多个帧组成, 这些帧可以乱序发送, 然后根据每个帧首部的流标识符重新组装。