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

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

[[398710]]

本文转载自微信公众号「三分钟学前端」,作者sisterAn。转载本文请联系三分钟学前端公众号。

引言

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

  • HTTP/1.1发明以来发生了哪些变化?
  • HTTP/1.1 协议的性能缺陷
  • HTTP/2 新特性
  • HTTP/2 遗留问题

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

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

  • 消息变大 :从几 KB 大小的消息,到几 MB 大小的消息;
  • 页面资源变多 :从每个页面不到 10 个的资源,到每页超 100 多个资源;
  • 内容形式变多样 :从单纯到文本内容,到图片、视频、音频等内容;
  • 实时性要求变高 :对页面的实时性要求的应用越来越多;

正如下图所示,从 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)

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

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

  • 使用多个域名 :将同一个页面的资源分散到不同域名,提升并发连接上限,因为浏览器通常对同一域名的 HTTP 连接最大只能是 6 个
  • 引入雪碧图 :将多张小图合并成一张大图供浏览器 JavaScript 来切割使用,这样可以将多个请求合并成一个请求,但是带来了新的问题,当某张小图片更新了,那么需要重新请求大图片,浪费了大量的网络带宽;
  • 将小图内联 :将图片的二进制数据通过 base64 编码后,把编码数据嵌入到 HTML 或 CSS 文件中,以此来减少网络请求次数;
  1. .icon { 
  2.     background: url(data:image/png;base64,<data>) no-repeat; 

使用 webpack 等工具打包 :打包压缩多个 JavaScript 文件到一个文件中,以一个请求替代了很多个请求,但是带来的问题,当某个 js 文件变化了,需要重新请求同一个包里的所有 js 文件;

按需加载 :来减少第一时间的 HTTP 请求次数

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下还会拥塞吗?

由于 TCP 连接减少而使网络拥塞状况得以改观;

慢启动时间减少,拥塞和丢包恢复速度更快。

参考

解密 HTTP/2 与 HTTP/3 的新特性:https://www.infoq.cn/article/ku4okqr8vh123a8dlccj

 

责任编辑:武晓燕 来源: 三分钟学前端
相关推荐

2023-09-06 12:01:50

HTTP协议信息

2015-10-30 15:42:05

HTTP网络协议

2019-11-17 22:47:53

HTTP23

2024-09-30 08:43:33

HttpgolangTimeout

2024-11-05 08:16:04

HTTP/3HTTP 2.0QUIC

2019-12-13 09:14:35

HTTP2协议

2014-11-13 10:57:03

http协议

2016-02-26 15:50:40

HTTP2

2009-06-16 11:24:00

HTTP增强Java SE 6新特

2023-11-10 08:03:00

2023-10-20 08:14:21

2022-08-26 17:14:37

HTTP 1.0HTTP 1.1HTTP

2017-05-04 20:29:12

HTTP服务器TCP

2019-01-14 15:31:42

HTTP23

2019-04-24 08:00:00

HTTPSHTTP前端

2023-11-21 22:23:06

2021-10-30 19:57:00

HTTP2 HTTP

2020-09-28 06:48:15

HTTP协议版本

2021-05-12 08:20:53

开发

2011-05-17 09:40:18

SQL Server IBM DB2
点赞
收藏

51CTO技术栈公众号