详解 HTTP/2 四大核心特性

HTTP/2 是 HTTP 协议自 1999 年 HTTP 1.1 发布后的首个更新,主要基于 SPDY 协议。由互联网工程任务组(IETF)的 Hypertext Transfer Protocol Bis(httpbis)工作小组进行开发。该组织于2014年12月将HTTP/2标准提议递交至IESG进行讨论,于2015年2月17日被批准。HTTP/2标准于2015年5月以RFC 7540正式发表。

HTTP/1.1 不足

  1. 高延迟 – 带来页面加载速度的降低
  2. 无状态特性 – 带来的巨大HTTP头部
  3. 明文传输 – 带来的不安全性
  4. 不支持服务器推送消息

SPDY 协议与 HTTP/2 简介

SPDY 协议

由于 HTTP/1.x 的缺陷,直到 2009 年,谷歌公开了自行研发的 SPDY 协议,主要解决 HTTP/1.1 效率不高的问题。谷歌推出 SPDY,才算是正式改造HTTP协议本身。降低延迟,压缩 header 等等,SPDY 的实践证明了这些优化的效果,也最终带来 HTTP/2 的诞生。

image

HTTP/1.1 有两个主要的缺点:安全不足和性能不高 , 如上图所示, SPDY 位于 HTTP 之下,TCP 和 SSL 之上,这样可以轻松兼容老版本的 HTTP 协议(将 HTTP1.x 的内容封装成一种新的 frame 格式),同时可以使用已有的 SSL 功能。

SPDY 协议在 Chrome 浏览器上证明可行以后,就被当作 HTTP/2 的基础,主要特性都在 HTTP/2 之中得到继承。

HTTP/2 协议

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

HTTP/2 由两个规范(Specification)组成:

  1. Hypertext Transfer Protocol version 2 - RFC7540

  2. HPACK - Header Compression for HTTP/2 - RFC7541

HTTP/2 四大特性

二进制分帧

先理解两个概念:

  1. 帧:HTTP/2 数据通信的最小单位消息:指 HTTP/2 中逻辑上的 HTTP 消息。例如请求和响应等,消息由一个或多个帧组成。
  2. 流:存在于连接中的一个虚拟通道。流可以承载双向消息,每个流都有一个唯一的整数 ID。

HTTP/2 传输数据量的大幅减少,主要有两个原因:

  1. 以二进制方式传输和 Header 压缩。我们先来介绍二进制传输, HTTP/2 采用二进制格式传输数据,而非 HTTP/1.x 里纯文本形式的报文,二进制协议解析起来更高效。
  2. HTTP/2 将请求和响应数据分割为更小的帧,并且它们采用二进制编码。

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

多路复用

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

image

在 HTTP/2 中,有了二进制分帧之后,HTTP/2 不再依赖 TCP 链接去实现多流并行了,在 HTTP/2 中:

  • 同域名下所有通信都在单个连接上完成。

  • 单个连接可以承载任意数量的双向数据流。

  • 数据流以消息的形式发送,而消息又由一个或多个帧组成,多个帧之间可以乱序发送,因为根据帧首部的流标识可以重新组装。

这一特性,使性能有了极大提升:

  • 同个域名只需要占用一个 TCP 连接,使用一个连接并行发送多个请求和响应,消除了因多个 TCP 连接而带来的延时和内存消耗。

  • 并行交错地发送多个请求,请求之间互不影响。

  • 并行交错地发送多个响应,响应之间互不干扰。

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

image

如上图所示,多路复用的技术可以只通过一个 TCP 连接就可以传输所有的请求数据。

首部压缩

HTTP/2 并没有使用传统的压缩算法,而是开发了专门的 “HPACK” 算法,在客户端和服务器两端建立“字典”,用索引号表示重复的字符串,还
采用哈夫曼编码来压缩整数和字符串 ,可以达到 50%~90% 的高压缩率。

具体来说:

  • 在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键-值对,对于相同的数据,不再通过每次请求和响应发送;

  • 首部表在 HTTP/2 的连接存续期内始终存在,由客户端和服务器共同渐进地更新;

  • 每个新的首部键-值对要么被追加到当前表的末尾,要么替换表中之前的值。

例如下图中的两个请求, 请求一发送了所有的头部字段,第二个请求则只需要发送差异数据,这样可以减少冗余数据,降低开销。

image

服务器推送

HTTP/2 还在一定程度上改变了传统的 “请求-应答” 工作模式,服务器不再是完全被动地响应请求,也可以新建“流”主动向客户端发送消息。比如,在浏览器刚请求HTML的时候就提前把可能会用到的JS、CSS文件发给客户端,减少等待的延迟,这被称为”服务器推送”( Server Push,也叫 Cache push)。

例如下图所示,服务端主动把 JS 和 CSS 文件推送给客户端,而不需要客户端解析 HTML 时再发送这些请求。

image

另外需要补充的是,服务端可以主动推送,客户端也有权利选择是否接收。如果服务端推送的资源已经被浏览器缓存过,浏览器可以通过发送RST_STREAM帧来拒收。主动推送也遵守同源策略,换句话说,服务器不能随便将第三方资源推送给客户端,而必须是经过双方确认才行。

----------本文结束感谢您的阅读----------
xiaolong wechat
一只程序猿对世界的不完全理解