"队头堵塞": 在 1.1 版协议中,虽然可以在一个 TCP 中发送多个请求,服务器只有处理完一个回应,才会进行下一个回应。要是前面的回应特别慢,后面就会有许多请求排队等着。
为了避免这个问题,只有两种方法:一是减少请求数,二是同时多开持久连接。
所以产生了很多网页优化技巧,比如合并脚本和样式表,将图片嵌入 CSS 代码,域名分片等,但是 HTTP 协议设计得更好的话,这些工作完全没有必要做的。
4 SPDY 协议 (2009 年)2009 年,谷歌公开了自己搞的 SPDY 协议,主要为了解决 HTTP/1.1 效率不高的问题。
这个协议最终被当作了 HTTP/2 的基础。
5 HTTP 协议 2 版HTTP/2 协议不叫 HTTP/2.0,这是因为标准委员会不在打算发布子版本,下一个新的版本将会是 HTTP/3。
5.1 二进制协议HTTP 协议的头肯定是文本(ASCII 码),数据体可以是文本,也可以是二进制。
但 HTTP/2 协议头和数据体都是二进制,是一个彻彻底底的二进制协议。
这里的头和数据体都换了一个身份叫做 “帧”:头信息帧和数据帧。
二进制协议的好处就是可以定义额外的帧,HTTP/2 有近十种帧,为将来的高级应用打好了基础,因为二进制解析比文本解析更方便。
5.2 多工HTTP/2 协议复用 TCP 连接,也就是说客户端和服务端可以同时发送或者回应多个请求。
比如说,在一个 TCP 里,客户端给服务端发送了 A 和 B 两个请求,按道理说应该先处理 A 请求,但是服务端发现 A 请求有点费劲儿,就先把 A 请求中处理好的发出去,接着回应 B 请求,完事儿以后再发送 A 请求中剩下的部分。
像这样双向,实时的通信,就叫做多工(Multiplexing)。
5.3 数据流HTTP/2 的数据包不是按照顺序发送的,同一个连接里的数据包可能属于多个请求。所以需要一个编号,这个编号指明数据包属于哪一个请求或者回应。
这里有一个概念叫做数据流,我们把一个请求或者回应的所有数据包合在一起称为一个数据流。每个数据流都有一个独一无二的编号,数据包发送的时候都必须标定数据流编号。
客户端请求的数据流编号一律为基数,而服务端回应的数据流编号为偶数。
在 HTTP/1.1 中终止请求的方式只能是关闭 TCP 连接,而现在可以发送一个信号:(RST_STREAM 帧),取消这个数据流。
也就是说 HTTP/2 可以取消某一次请求,同时能保证 TCP 连接打开,可以被其他请求所使用。
此外,客户端可以指定数据流的优先级,优先级高的服务器越早响应。
5.4 头信息压缩因为协议不带有状态,每次请求都必须附上所有信息。有一些信息是重复的,这样会影响数据传输速度,浪费带宽。
HTTP/2 采用头信息压缩机制可以减少不利影响。首先是将信息压缩后再发送(gzip 或者 compress),其次是客户端 和服务器同时维护一张头信息表,这个表很神奇的地方在于可以利用索引进行管理,只要我们发送索引就可以表示我们传输的信息,这样就能够提高速度。
5.5 主动推送HTTP/2 允许服务器在没有经过允许的情况下,可以主动向客户端推送资源 。这个过程叫做服务器推送(server push)。
举一个例子,别发送邮件给我们的时候,邮箱会冒个弹框出来告诉我们有人往邮箱里投递了一封邮件。注意,此时我们并没有刷新网页。
服务器推送还可能用到消息提醒,静态资源自动推送到服务端等场景。