HTTP/2

前言

现在的互联网几乎全部使用的是HTTP/1.1作为传输协议,但是随着互联网的日益膨胀,HTTP/1.1协议的问题也被逐渐放大,HTTP/2作为下一代协议正在逐渐发展

HTTP协议演变历史

HTTP/1.0

HTTP/1.0 奠定了web基础, 默认使用的是短连接的方式

HTTP/1.1(1995年制定)

在HTTP/1.0的基础上做了如下改进:

  1. 默认使用长连接的方式(keepalive)
  2. 请求头信息进行扩展

HTTP/2

由google SPDY演化而来, 提升性能

短连接和长连接

短连接

浏览器会先发起一个 TCP 连接,拿到该网页的 HTML 源代码(拿到 HTML 之后,这个 TCP 连接就关闭了)。然后,浏览器开始分析这个网页的源码,知道这个页面包含很多外部资源(图片、CSS、JS)。然后针对【每一个】外部资源,再分别发起一个个 TCP 连接,把这些文件获取到本地(同样的,每抓取一个外部资源后,相应的 TCP 就断开)

长连接

浏览器也会先发起一个 TCP 连接去抓取页面。但是抓取页面之后,该 TCP 连接并不会立即关闭,而是暂时先保持着(所谓的“Keep-Alive”)。然后浏览器分析 HTML 源码之后,发现有很多外部资源,就用刚才那个 TCP 连接去抓取此页面的外部资源。

HTTP/1.x的主要问题

1. 并发能力有限

浏览器客户端在同一时间, 针对同一域名下的请求有一定的数量限制, 超过这个数量的请求会被阻塞

Clients that use persistent connections SHOULD limit the number of simultaneous connections that they maintain to a given server. A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy. A proxy SHOULD use up to 2*N connections to another server or proxy, where N is the number of simultaneously active users. These guidelines are intended to improve HTTP response times and avoid congestion

下面这张图, 显示了不同的浏览器设置的该参数:

2. 较高的协议负载

头信息和Cookies大约要800字节, http元数据没有压缩
HTTP/1.1不支持首部压缩

3. 不支持服务端推送

这个后面解释什么是服务端推送

HTTP/1.1 克服延迟

针对HTTP/1.1中存在的问题, 出现了很多的优化方案:

  1. Spriting
    将很多较小的图片合并成一张大图,再用JavaScript或者CSS将小图重新“切割”出来的技术
  2. 内联
    是另外一种防止发送很多小图请求的技巧,它将图片的原始数据嵌入在CSS文件里面的URL里

    1
    2
    3
    4
    5
    6
    .icon1 {
    background: url(data:image/png;base64,<data>) no-repeat;
    }
    .icon2 {
    background: url(data:image/png;base64,<data>) no-repeat;
    }
  3. 拼接
    将多个js文件合并为一个大的文件

  4. 分片
    客户端对某个域名的请求是有上限的, 那如果我们一个网站使用多个域名, 将资源分配到不到服务器上, 就可以增加连接数量

HTTP/2的主要特性

首先我们理想中的协议应该是这样:

1. 尽可能发送少的数据给服务器
2. 从服务器下载尽可能少的数据
3. 尽可能减少往返的次数

而HTTP/1.1是这样的:

现在我们到了HTTP/2,他的模型是这样的:

它解决了HTTP/1.1中遗留的问题, 使用了如下方案:

1. 连接多路复用

允许同时通过单一的 HTTP/2 连接发起多重的请求-响应消息

如何实现多路复用?
首先HTTP/2中定义了一个非常重要的概念要叫做frame(帧)

在二进制分帧层中,HTTP/2会将所有传输的信息分割为更小的消息和帧(frame),并对它们采用二进制格式的编码, 其中 HTTP1.x 的首部信息会被封装到 HEADER frame,而相应的 Request Body 则封装到DATA frame里面

最后多路复用的示意图如下:

2. 压缩http头部数据

HTTP/1.1并不支持首部压缩, 为此SPDY和HTTP/2进行改进, 它们使用的压缩算法不同

3. 支持服务端数据推送

上面我们看到HTTP/2的请求交互图*, 当客户端第一次向服务器发送首页请求之后, 服务器知道客户端需要什么, 它使用Server Push发送多个响应给客户端. 从而较少了客户端与服务端的交互, 充分利用了网络资源

HTTP/1.1 和 HTTP/2比较演示

下面是Akamai公司建立的一个官方的演示, 用以HTTP/1.1和HTTP/2在性能上的比较, 这里我们必须使用支持HTTP/2的浏览器才能打开HTTP/2 is the future of the Web, and it is here!进行测试(chrome和firefox当然是支持的, IE就呵呵了)

可以看出: 同时请求相同数量的图片, HTTP/2所花费的时间更短(每次执行结果会不一致)

HTTP/2的使用情况

  1. curl
    curl需要一个叫做nghttp2的库来支持http2帧层功能
    先安装nghttp2, 然后升级curl
  2. nginx已经支持
  3. 浏览器支持
    下图显示了目前支持HTTP/2的浏览器情况:

参考

聊聊HTTPS和SSL/TLS协议
HTTP2 讲解
HTTP/2.0 相比1.0有哪些重大改进?
HTTP/2 对现在的网页访问,有什么大的优化呢?体现在什么地方?
如何启用curl命令HTTP2支持
使用HTTP/2提升性能的7个建议