先看看HTTP/1.1的特性,和仍然存在的问题。

HTTP/1.1 为网络效率做了大量的优化,最核心的有如下三种方式:
增加了持久连接;
浏览器为每个域名最多同时维护 6 个 TCP 持久连接;
使用 CDN 的实现域名分片机制。

将一个页面的资源利用多个域名下载,提高tcp并发数量。http2中已不需要。

引入了 CDN,并同时为每个域名维护 6 个连接,这样就大大减轻了整个资源的下载时间。
这里我们可以简单计算下:
如果使用单个 TCP 的持久连接,下载 100 个资源所花费的时间为 100 n RTT;
若通过上面的技术,就可以把整个时间缩短为 100 n RTT/(6 * CDN 个数)。从这个计算结果来看,我们的页面加载速度变快了不少。

HTTP/1.1的主要问题:带宽利用率不高

虽然有域名分片,有长连接,有6个TCP连接。但是对带宽的利用率却不高。
主要原因是两个:
1.TCP的慢启动。有时候TCP慢启动所占用的时间,比传输html,js,css的时间都要长。

2.多个TCP连接会竞争宽带资源。带宽整体大小是固定的,但是若干的TCP连接会竞争带宽,导致每个tcp连接能用的带宽资源并不高。如果有的传输的是js,有的传输的是图片,音视频,但是http1.1传输资源时没有优先级的概念,所以会导致重要的资源可能传输的慢。

3.队头阻塞。在HTTP/1.1中,一个TCP连接,好比一个管道,只能同时进行一个请求。前面的请求处理不好,后面的请求就得等着。此时白白浪费了服务器的带宽和CPU资源。队头堵塞使得请求不能并行处理,造成了资源的浪费。注意,这里的队头阻塞,是HTTP协议的队头阻塞,不是TCP协议的对头阻塞。

多路复用

上面分析的3个问题,前两个是TCP协议的问题。HTTP2还是基于的TCP。所以并没有解决掉,只能尽量规避。
但是HTTP/1.1的队头阻塞,在HTTP2可以解决掉,方案就是:

HTTP/2 最核心、最重要且最具颠覆性的多路复用机制

HTTP/2 的思路就是:
一个域名只使用一个 TCP 长连接来传输数据,这样整个页面资源的下载过程只需要经历一次慢启动,同时也避免了多个 TCP 连接竞争带宽所带来的问题。

队头阻塞的问题,等待请求完成后才能去请求下一个资源,这种方式无疑是最慢的,所以 HTTP/2 需要实现资源的并行请求,也就是任何时候都可以将请求发送给服务器,而并不需要等待其他请求的完成,然后服务器也可以随时返回处理好的请求资源给浏览器。

所以,HTTP/2 的解决方案可以总结为:一个域名只使用一个 TCP 长连接和消除队头阻塞问题
可以参考下图:

多路复用的实现:二进制分帧

HTTP/2的基石就是二进制帧
http/2虚拟了一个stream流的概念,一个stream就对应着以前一次请求-响应的过程。

Stream就是二进制帧的双向传输序列。

以前的message报文,是ASCII编码的明文,在传输时不可分割,所以请求和响应都是有顺序的。
而http/2,采用了二进制帧frame,是和tcp一样的二进制数据,是一种更小的单位,
一个stream中有若干个frame用来传输报文message。

开始我不明白,数据在传输时不都是二进制的吗,为什么http2采用了二进制帧,就能提高效率了。

后来明白了,网络是分层的,以前的http层,报文数据是ASCII编码的,到了tcp层才被编译为二进制数据
而到了HTTP2,从它这一层,报文数据就是二进制的frame

以前http1.1,请求的发送和响应,在http应用层,必须是请求-响应这样对应的,
所以在http层存在队头阻塞。报文来到tcp层,
到了tcp层转为二进制数据,最小单位是tcp包,要保证传输的可靠性,有个特别的“丢包重传”机制,丢失的包必须要等待重新传输确认,其他的包即使已经收到了,也只能放在缓冲区里,上层的应用拿不出来,只能“干着急”。这是TCP层的队头阻塞。

到了HTTP/2,在http层,报文都是二进制帧,
HTTP/2 虽然使用“帧”“流”“多路复用”,没有了“队头阻塞”,但这些手段都是在应用层里,而在下层,也就是 TCP 协议里,还是会发生“队头阻塞”。

总结

我们首先分析了影响 HTTP/1.1 效率的三个主要因素:TCP 的慢启动、多条 TCP 连接竞争带宽和队头阻塞。

接下来我们分析了 HTTP/2 是如何采用多路复用机制来解决这些问题的。

多路复用是通过在协议栈中添加二进制分帧层来实现的,有了二进制分帧层还能够实现请求的优先级、服务器推送、头部压缩等特性,从而大大提升了文件传输效率。

HTTP/2 协议规范于 2015 年 5 月正式发布,在那之后,该协议已在互联网和万维网上得到了广泛的实现和部署。从目前的情况来看,国内外一些排名靠前的站点基本都实现了 HTTP/2 的部署。

使用 HTTP/2 能带来 20%~60% 的效率提升,至于 20% 还是 60% 要看优化的程度。总之,我们也应该与时俱进,放弃 HTTP/1.1 和其性能优化方法,去“拥抱”HTTP/2。

思考时间