HTTP/2对比HTTP/1.1,新特性是什么?是如何解决队头阻塞与压缩头部的?

394次阅读  |  发布于3年以前

引言

本文主要通过以下四个方面介绍,循序渐进走进HTTP/2:

HTTP/1.1发明以来发生了哪些变化?

近年来,如果你仔细观察那些最流行的网站首页所需要下载的资源的话,会发现一个非常明显的趋势:

正如下图所示,从 2011 年以来, 传输数据大小与平均请求资源数量不断持续增长,并没有减缓的迹象(绿色:传输数据大小,红色:平均请求资源数量):

自从 1997 年 HTTP/1.1 发布以来,我们已经使用 HTTP/1.x 相当长一段时间了,但近几年内容的爆炸式成长使得 HTTP/1.1 越来越无法满足现代网络的需求了

HTTP/1.1 协议的性能缺陷

1. 高延迟:页面访问速度下降

虽然近几年来网络带宽增长非常快,然而我们却并没有看到网络延迟有对应程度的降低,这主要是由于队头阻塞 (Head-Of-Line Blocking)问题导致

HTTP/1.1 版引入了管道机制(pipelining),即在同一个TCP连接里面,客户端可以同时发送多个请求,进一步改进了 HTTP 协议的效率

但这要求服务端必须按照请求发送的顺序返回响应,当顺序请求多个文件时,其中一个请求因为某种原因被阻塞时,在后面排队的所有请求也一并被阻塞,这就是队头阻塞 (Head-Of-Line Blocking)

队头阻塞导致再打的带宽无法被充分利用

因此 人们尝试过以下办法来解决队头阻塞问题:

.icon {
    background: url(data:image/png;base64,<data>) no-repeat;
}

2. 明文传输:不安全

HTTP/1.1 在传输数据时,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份,这在一定程度上无法保证数据的安全性。

3. 无状态:头部巨大切重复

由于 HTTP 协议是无状态的,每一个请求都得携带 HTTP 头部,特别是对于有携带 cookie 的头部,而 cookie 的大小通常很大,另外还有User Agent、Accept、Server等,通常多达几百字节甚至上千字节,但 Body 却经常只有几十字节

4. 不支持服务器推送

HTTP/1.1 不支持服务器推送消息,因此当客户端需要获取通知时,只能通过定时器不断地拉取消息,这无疑浪费大量了带宽和服务器资源。

HTTP/2 新特性

在 HTTP/1.x 中,为了性能考虑,我们会引入雪碧图、将小图内联、使用多个域名等等的方式,但还是有一些关键点无法优化,例如HTTP头部巨大且重复、明文传输不安全、服务器不能主动推送等,要改变这些必须重新设计 HTTP 协议,于是 HTTP/2 就出来了!

2015 年,HTTP/2 发布。HTTP/2 是现行 HTTP 协议(HTTP/1.x)的替代,但它不是重写,HTTP 方法 / 状态码 / 语义都与 HTTP/1.x 一样。HTTP/2 基于 SPDY,专注于性能,最大的目标是在用户和网站间只用一个连接(connec-tion)

从目前的情况来看,国内外一些排名靠前的站点基本都实现了 HTTP/2 的部署,使用 HTTP/2 能带来 20%~60% 的效率提升。

可以通过该链接直观感受下 HTTP/2 比 HTTP/1 到底快了多少: https://http2.akamai.com/demo

1. 二进制传输

在不改动 HTTP/1.x 的语义、方法、状态码、URI 以及首部字段….. 的情况下,HTTP/2 是如何做到「突破 HTTP1.1 的性能限制,改进传输性能,实现低延迟和高吞吐量」的 ?

关键之一就是在应用层(HTTP/2)和传输层(TCP or UDP)之间增加一个二进制分帧层。

在二进制分帧层中, HTTP/2 会将所有传输的信息分割为更小的消息和帧(frame),并对它们采用二进制格式的编码,其中 HTTP1.x 的首部信息会被封装到 HEADERS 帧,而相应的 Request Body 则封装到 DATA 帧里面,HTTP/2 数据分帧后,“Header+Body"的报文结构就完全消失了,协议看到的只是一个个"碎片”。

HTTP/2 中,同域名下所有通信都在单个连接上完成,该连接可以承载任意数量的双向数据流。每个数据流都以消息的形式发送,而消息又由一个或多个帧组成。多个帧之间可以乱序发送,根据帧首部的流标识可以重新组装

2. Header 压缩(HPACK)

HTTP 协议不带有状态,每次请求都必须附上所有信息。所以,请求的很多字段都是重复的,比如Cookie和User Agent,一模一样的内容,每次请求都必须附带,这会浪费很多带宽,也影响速度。

HTTP/2 对这一点做了优化,引入了头信息压缩机制(header compression)。一方面,头信息使用gzip或compress压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。

3. 多路复用

在 HTTP/2 中引入了多路复用的技术。多路复用很好地解决了浏览器限制同一个域名下请求数量的问题,同时也更容易实现全速传输,毕竟新开一个 TCP 连接都需要慢慢提升传输速度。

多路复用,就是在一个 TCP 连接中可以存在多条流。换句话说,也就是可以发送多个请求,对端可以通过帧中的标识知道属于哪个请求。

这一特性使得 HTTP 传输性能得到极大提升,主要体现在以下三个方面:

多工

HTTP/2 复用 TCP 连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,而且不用按照顺序一一对应,这样就避免了"队头堵塞"

数据流

HTTP/2 并行交错地发送多个请求 / 响应,请求 / 响应之间互不影响

因此,必须要对数据包做标记,指出它属于哪个请求 / 响应。

HTTP/2 将每个请求或回应的所有数据包,称为一个数据流(stream)。每个数据流都有一个独一无二的编号。数据包发送的时候,都必须标记数据流ID,用来区分它属于哪个数据流。另外还规定,客户端发出的数据流,ID一律为奇数,服务器发出的,ID为偶数。

数据流发送到一半的时候,客户端和服务器都可以发送信号(RST_STREAM帧),取消这个数据流。1.1版取消数据流的唯一方法,就是关闭TCP连接。这就是说,HTTP/2 可以取消某一次请求,同时保证TCP连接还打开着,可以被其他请求使用。

优先级

在 HTTP/2 中,每个请求都可以带一个 31bit 的优先值,0 表示最高优先级, 数值越大优先级越低。有了这个优先值,客户端和服务器就可以在处理不同的流时采取不同的策略,以最优的方式发送流、消息和帧。

4. 服务端 Push

HTTP/2 允许服务器未经请求,主动向客户端发送资源,这叫做服务器推送(server push)。

常见场景是客户端请求一个网页,这个网页里面包含很多静态资源。正常情况下,客户端必须收到网页后,解析HTML源码,发现有静态资源,再发出静态资源请求。其实,服务器可以预期到客户端请求网页后,很可能会再请求静态资源,所以就主动把这些静态资源随着网页一起发给客户端了。

这样就可以相对减少一点延迟时间。当然在浏览器兼容的情况下你也可以使用 prefetch 。

注意: 服务端可以主动推送,客户端也可以主动选择是否接收,如果服务端推送的资源已经被浏览器缓存过,浏览器可以通过发送 RST_STREAM 帧来拒收,另外,主动推送也遵守同源策略

5. 提高安全性

出于兼容的考虑,HTTP/2 延续了 HTTP/1 的“明文”特点,可以像以前一样使用明文传输数据,不强制使用加密通信,但 HTTPS 已经是大势所趋,各大主流浏览器都公开宣布只支持加密的 HTTP/2,所以,真实应用中的 HTTP/2 是还是加密的:

HTTP/2 遗留问题

HTTP/2 还会队头阻塞吗?

HTTP/2 也存在队头阻塞问题,比如丢包。

如果造成队头阻塞,问题可能比http1.1还严重,因为只有一个tcp连接,后续的传输都要等前面,http/1.1 多个tcp连接,阻塞一个,其他的还可以正常跑

HTTP/2下还会拥塞吗?

参考

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8