一张图可以很较为全面的概括了HTTP/1.*存在缺陷:
前端一般采用: - CSS Spriting,小图合并成大图,CSS进行分割成小图显示 - Inlining,使用DataURL方式内嵌Base64编码格式图片 - JS Concatenation,多个JS文件合并成一个,缺陷是一旦有文件修改,需要重新合并 - Sharding,将资源/服务部署到多个机器上,均摊/分享请求压力
HTTP/1.*没有充分利用TCP特性,再加上同一个站点打开多个连接等,导致网络资源利用率不高。
与HTTP/1相比,主要区别包括:
这里有一张图,可以总体上了解HTTP/2:
保留/兼容HTTP/1.1的所有语义,但传输语法(或者说传输方式)改变,目的在于更充分利用TCP更高效传输,多路复用是实现途径,低延迟是改进方向。
以上为简单总体介绍了HTTP/2协议,要想深入其特性,需要阅读器规范。下面为围绕HTTP/2规范的各个方面,列出提纲,便于后面一一填充。
以下名词会在当前或以后笔记中出现,贴出来方便理解。
HTTP/2相比HTTP/1.1,可以做到更有效的充分利用TCP连接,避免了TCP连接的重复的创建(三次握手)、销毁(四次挥手)的过程。
HTTP/2协议在TCP连接之初进行协商通信,只有协商成功,才会涉及到后续的请求-响应等具体的业务型数据交换。
针对直接建立在标准TCP之上HTTP2,在未知服务器是否提供HTTP/2支持之前,可以依赖现有HTTP/1.1进行试探。
GET / HTTP/1. 1 Host: server. example. com Connection: Upgrade, HTTP2-Settings Upgrade: h2c HTTP2-Settings: <base64url encoding of HTTP/2 SETTINGS payload>
HTTP/1. 1 200 OK Content-Length: 243 Content-Type: text/html . . .
服务器支持HTTP/2,通知客户端一起切换到HTTP/2协议下吧
HTTP/1. 1 101 Switching Protocols Connection: Upgrade Upgrade: h2c [ HTTP/2 connection . . .
PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n // 纯字符串表示,翻译成字节数为24个字节 SETTINGS帧 // 其负载可能为空服务器端和客户端所发送的连接序言有所不同。
客户端预先知道服务器提供HTTP/2支持,可以免去101协议切换的流程开销。 具体流程:
PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n // 纯字符串表示,翻译成字节数为24个字节 SETTINGS帧 // 其负载可能为空
HTTP/2安全版本在TLS上构建,协商采用的ALPN扩展协议,采用“h2”作为协议标识符(http版本则是“h2c”)。一定程度上可认为不存在试探是否支持或直接连接的烦恼,因为这个过程直接在TLS层协商而成。
流程如下:
HTTPS协商是强制,封装在TLS之上ALPN扩展实现,HTTP只有非直接连接方式才会存在通过101 协议切换方式进行升级。
这里有一张图形象说明其流程。
这里不论是HTTP还是HTTPS,在两端成功协商之后(或HTTP的直接连接),其连接过程都是一样的
HTTP/2连接的建立协商机制比HTTP/1.1稍微复杂了一些。
对比明文版的HTTP/1.1和HTTP/2完成一次请求-响应:
在弱网络环境下,会不会加重网络负载,只能拭目一看了。
流(Stream),服务器和客户端在HTTP/2连接内用于交换帧数据的独立双向序列,逻辑上可看做一个较为完整的交互处理单元,即表达一次完整的资源请求-响应数据交换流程;一个业务处理单元,在一个流内进行处理完毕,这个流生命周期完结。
特点如下:
流的概念提出是为了实现多路复用,在单个连接上实现同时进行多个业务单元数据的传输。逻辑图如下:
实际传输可能是这样的:
只看到帧(Frame),没有流(Stream)嘛。
需要抽象化一些,就好理解了:
这样简单梳理,就有些小清晰了。
流的概念提出,就是为了实现多路复用。影响因素:
流总体组成如下:
搞清楚了流和多路复用之间关系,下面稍微深入一点,学习流的一些细节。
帧的行为以及END_STREAM标志位都会对流的状态的产生变化。因为流由各个端独立创建,没有协商,消极后果就是(两端无法匹配的流的状态)导致发送完毕RST_STREAM帧之后“关闭”状态受限,因为帧的传输和接收需要一点时间。
帧的状态列表:
reserved,为推送保留一个流稍后使用
reserved (remote),客户端接收到PUSH_PROMISE帧,本地预留的一个用于接收推送流所处于的状态
不满足条件,需要报PROTOCOL_ERROR类型连接错误
half closed
half closed (remote),接收到包含有END_STREAM标志位帧的一端,流进入远程半关闭状态
一旦接收或发送RST_STREAM帧,流将进入"closed"状态。
要求如下:
流的优先级在于允许终端向对端表达所期待的给予具体流更多资源支持的意见的表达,不能保证对端一定会遵守,非强制性需求建议;默认值16。在资源有限时,可以保证基本数据的传输。
优先级改变:
A A / \ ==> /|\ B C B D C
A A | / \ ==> D B C / \ B C
? ? ? ? | / \ | | A D A D D / \ / / \ / \ | B C ==> F B C ==> F A OR A / \ | / \ /|\ D E E B C B C F | | | F E E (intermediate) (non-exclusive) (exclusive)
多路复用会引入资源竞争,流量控制可以保证流之间不会严重影响到彼此。流量控制通过使用WINDOW_UPDATE帧实现,可作用于单个流以及整个的连接。一些原则如下:
需要注意事项:
HTTP/2规范中所定义的流概念、属性很复杂,在请求量很大以及应对海量并发的情况下,整个连接的流量控制+单个流的流量控制+流的状态+流优先级属性+优先级的状态+流依赖树形模型等一系列新特性,可能会造成: