一文读懂HTTP/2 及 HTTP/3特性

前言

HTTP/2 相比于 HTTP/1,能够说是大幅度提升了网页的性能,只须要升级到该协议就能够减小不少以前须要作的性能优化工做,固然兼容问题以及如何优雅降级应该是国内还不广泛使用的缘由之一。html

虽然 HTTP/2 提升了网页的性能,可是并不表明它已是完美的了,HTTP/3 就是为了解决 HTTP/2 所存在的一些问题而被推出来的。前端

想阅读更多优质文章请猛戳GitHub博客git

1、HTTP协议

HTTP协议是HyperText Transfer Protocol(超文本传输协议)的缩写,它是互联网上应用最为普遍的一种网络协议。全部的WWW文件都必须遵照这个标准。伴随着计算机网络和浏览器的诞生,HTTP1.0也随之而来,处于计算机网络中的应用层,HTTP是创建在TCP协议之上,因此HTTP协议的瓶颈及其优化技巧都是基于TCP协议自己的特性,例如tcp创建链接的3次握手和断开链接的4次挥手以及每次创建链接带来的RTT延迟时间。github

2、HTTP/1.x的缺陷

  • 链接没法复用:链接没法复用会致使每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显,慢启动则对大量小文件请求影响较大(没有达到最大窗口请求就被终止)。面试

    • HTTP/1.0传输数据时,每次都须要从新创建链接,增长延迟。
    • HTTP/1.1虽然加入keep-alive能够复用一部分链接,但域名分片等状况下仍然须要创建多个connection,耗费资源,给服务器带来性能压力。
  • Head-Of-Line Blocking(HOLB):致使带宽没法被充分利用,以及后续健康请求被阻塞。HOLB是指一系列包(package)由于第一个包被阻塞;当页面中须要请求不少资源的时候,HOLB(队头阻塞)会致使在达到最大请求数量时,剩余的资源须要等待其余资源请求完成后才能发起请求。浏览器

    • HTTP 1.0:下个请求必须在前一个请求返回后才能发出,request-response对按序发生。显然,若是某个请求长时间没有返回,那么接下来的请求就所有阻塞了。
    • HTTP 1.1:尝试使用 pipeling 来解决,即浏览器能够一次性发出多个请求(同个域名,同一条 TCP 连接)。但 pipeling 要求返回是按序的,那么前一个请求若是很耗时(好比处理大图片),那么后面的请求即便服务器已经处理完,仍会等待前面的请求处理完才开始按序返回。因此,pipeling 只部分解决了 HOLB。

如上图所示,红色圈出来的请求就因域名连接数已超过限制,而被挂起等待了一段时间。

  • 协议开销大: HTTP1.x在使用时,header里携带的内容过大,在必定程度上增长了传输的成本,而且每次请求header基本不怎么变化,尤为在移动端增长用户流量。
  • 安全因素:HTTP1.x在传输数据时,全部传输的内容都是明文,客户端和服务器端都没法验证对方的身份,这在必定程度上没法保证数据的安全性

3、SPDY 协议

由于HTTP/1.x的问题,咱们会引入雪碧图、将小图内联、使用多个域名等等的方式来提升性能。不过这些优化都绕开了协议,直到2009年,谷歌公开了自行研发的 SPDY 协议,主要解决HTTP/1.1效率不高的问题。谷歌推出SPDY,才算是正式改造HTTP协议自己。下降延迟,压缩header等等,SPDY的实践证实了这些优化的效果,也最终带来HTTP/2的诞生。缓存

SPDY 协议在Chrome浏览器上证实可行之后,就被看成 HTTP/2 的基础,主要特性都在 HTTP/2 之中获得继承。安全

4、HTTP/2 简介

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

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

  1. Hypertext Transfer Protocol version 2 - RFC7540
  2. HPACK - Header Compression for HTTP/2 - RFC7541

5、HTTP/2 新特性

1.二进制传输

HTTP/2 采用二进制格式传输数据,而非 HTTP 1.x 的文本格式,二进制协议解析起来更高效。 HTTP / 1 的请求和响应报文,都是由起始行,首部和实体正文(可选)组成,各部分之间以文本换行符分隔。HTTP/2 将请求和响应数据分割为更小的帧,而且它们采用二进制编码

接下来咱们介绍几个重要的概念:

  • 流:流是链接中的一个虚拟信道,能够承载双向的消息;每一个流都有一个惟一的整数标识符(一、2…N);
  • 消息:是指逻辑上的 HTTP 消息,好比请求、响应等,由一或多个帧组成。
  • 帧:HTTP 2.0 通讯的最小单位,每一个帧包含帧首部,至少也会标识出当前帧所属的流,承载着特定类型的数据,如 HTTP 首部、负荷,等等

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

2.多路复用

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

你们能够经过 该连接 直观感觉下 HTTP/2 比 HTTP/1 到底快了多少。

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

  • 同域名下全部通讯都在单个链接上完成。
  • 单个链接能够承载任意数量的双向数据流。
  • 数据流以消息的形式发送,而消息又由一个或多个帧组成,多个帧之间能够乱序发送,由于根据帧首部的流标识能够从新组装。

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

  • 同个域名只须要占用一个 TCP 链接,使用一个链接并行发送多个请求和响应,消除了因多个 TCP 链接而带来的延时和内存消耗。
  • 并行交错地发送多个请求,请求之间互不影响。
  • 并行交错地发送多个响应,响应之间互不干扰。
  • 在HTTP/2中,每一个请求均可以带一个31bit的优先值,0表示最高优先级, 数值越大优先级越低。有了这个优先值,客户端和服务器就能够在处理不一样的流时采起不一样的策略,以最优的方式发送流、消息和帧。

如上图所示,多路复用的技术能够只经过一个 TCP 链接就能够传输全部的请求数据。

3.Header 压缩

在 HTTP/1 中,咱们使用文本的形式传输 header,在 header 携带 cookie 的状况下,可能每次都须要重复传输几百到几千的字节。

为了减小这块的资源消耗并提高性能, HTTP/2对这些首部采起了压缩策略:

  • HTTP/2在客户端和服务器端使用“首部表”来跟踪和存储以前发送的键-值对,对于相同的数据,再也不经过每次请求和响应发送;
  • 首部表在HTTP/2的链接存续期内始终存在,由客户端和服务器共同渐进地更新;
  • 每一个新的首部键-值对要么被追加到当前表的末尾,要么替换表中以前的值

例以下图中的两个请求, 请求一发送了全部的头部字段,第二个请求则只须要发送差别数据,这样能够减小冗余数据,下降开销

4.Server Push

Server Push即服务端能经过push的方式将客户端须要的内容预先推送过去,也叫“cache push”。

能够想象如下状况,某些资源客户端是必定会请求的,这时就能够采起服务端 push 的技术,提早给客户端推送必要的资源,这样就能够相对减小一点延迟时间。固然在浏览器兼容的状况下你也可使用 prefetch。 例如服务端能够主动把JS和CSS文件推送给客户端,而不须要客户端解析HTML时再发送这些请求。

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

6、HTTP/3 新特性

1.HTTP/3简介

虽然 HTTP/2 解决了不少以前旧版本的问题,可是它仍是存在一个巨大的问题,主要是底层支撑的 TCP 协议形成的。

上文提到 HTTP/2 使用了多路复用,通常来讲同一域名下只须要使用一个 TCP 链接。但当这个链接中出现了丢包的状况,那就会致使 HTTP/2 的表现状况反倒不如 HTTP/1 了。

由于在出现丢包的状况下,整个 TCP 都要开始等待重传,也就致使了后面的全部数据都被阻塞了。可是对于 HTTP/1.1 来讲,能够开启多个 TCP 链接,出现这种状况反到只会影响其中一个链接,剩余的 TCP 链接还能够正常传输数据。

那么可能就会有人考虑到去修改 TCP 协议,其实这已是一件不可能完成的任务了。由于 TCP 存在的时间实在太长,已经充斥在各类设备中,而且这个协议是由操做系统实现的,更新起来不大现实。

基于这个缘由,Google 就更起炉灶搞了一个基于 UDP 协议的 QUIC 协议,而且使用在了 HTTP/3 上,HTTP/3 以前名为 HTTP-over-QUIC,从这个名字中咱们也能够发现,HTTP/3 最大的改造就是使用了 QUIC。 QUIC 虽然基于 UDP,可是在本来的基础上新增了不少功能,接下来咱们重点介绍几个QUIC新功能。

2.QUIC新功能

  • 0-RTT

经过使用相似 TCP 快速打开的技术,缓存当前会话的上下文,在下次恢复会话的时候,只须要将以前的缓存传递给服务端验证经过就能够进行传输了。0RTT 建连能够说是 QUIC 相比 HTTP2 最大的性能优点。那什么是 0RTT 建连呢?

这里面有两层含义:

1.传输层 0RTT 就能创建链接。

2.加密层 0RTT 就能创建加密链接。

上图左边是 HTTPS 的一次彻底握手的建连过程,须要 3 个 RTT。就算是会话复用也须要至少 2 个 RTT。

而 QUIC 呢?因为创建在 UDP 的基础上,同时又实现了 0RTT 的安全握手,因此在大部分状况下,只须要 0 个 RTT 就能实现数据发送,在实现前向加密的基础上,而且 0RTT 的成功率相比 TLS 的会话记录单要高不少。

  • 多路复用

虽然 HTTP/2 支持了多路复用,可是 TCP 协议终究是没有这个功能的。QUIC 原生就实现了这个功能,而且传输的单个数据流能够保证有序交付且不会影响其余的数据流,这样的技术就解决了以前 TCP 存在的问题。

同HTTP2.0同样,同一条 QUIC链接上能够建立多个stream,来发送多个HTTP请求,可是,QUIC是基于UDP的,一个链接上的多个stream之间没有依赖。好比下图中stream2丢了一个UDP包,不会影响后面跟着 Stream3 和 Stream4,不存在 TCP 队头阻塞。虽然stream2的那个包须要从新传,可是stream三、stream4的包无需等待,就能够发给用户。

另外QUIC 在移动端的表现也会比 TCP 好。由于 TCP 是基于 IP 和端口去识别链接的,这种方式在多变的移动端网络环境下是很脆弱的。可是 QUIC 是经过 ID 的方式去识别一个链接,无论你网络环境如何变化,只要 ID 不变,就能迅速重连上。

  • 加密认证的报文

TCP 协议头部没有通过任何加密和认证,因此在传输过程当中很容易被中间网络设备篡改,注入和窃听。好比修改序列号、滑动窗口。这些行为有多是出于性能优化,也有多是主动攻击。

可是 QUIC 的 packet 能够说是武装到了牙齿。除了个别报文好比 PUBLIC_RESET 和 CHLO,全部报文头部都是通过认证的,报文 Body 都是通过加密的。

这样只要对 QUIC 报文任何修改,接收端都可以及时发现,有效地下降了安全风险。

如上图所示,红色部分是 Stream Frame 的报文头部,有认证。绿色部分是报文内容,所有通过加密。

  • 向前纠错机制

QUIC协议有一个很是独特的特性,称为向前纠错 (Forward Error Correction,FEC),每一个数据包除了它自己的内容以外,还包括了部分其余数据包的数据,所以少许的丢包能够经过其余包的冗余数据直接组装而无需重传。向前纠错牺牲了每一个数据包能够发送数据的上限,可是减小了由于丢包致使的数据重传,由于数据重传将会消耗更多的时间(包括确认数据包丢失、请求重传、等待新数据包等步骤的时间消耗)

假如说此次我要发送三个包,那么协议会算出这三个包的异或值并单独发出一个校验包,也就是总共发出了四个包。当出现其中的非校验包丢包的状况时,能够经过另外三个包计算出丢失的数据包的内容。固然这种技术只能使用在丢失一个包的状况下,若是出现丢失多个包就不能使用纠错机制了,只能使用重传的方式了

7、总结

  • HTTP/1.x 有链接没法复用、队头阻塞、协议开销大和安全因素等多个缺陷
  • HTTP/2 经过多路复用、二进制流、Header 压缩等等技术,极大地提升了性能,可是仍是存在着问题的
  • QUIC 基于 UDP 实现,是 HTTP/3 中的底层支撑协议,该协议基于 UDP,又取了 TCP 中的精华,实现了即快又可靠的协议

给你们推荐一个好用的BUG监控工具Fundebug,欢迎免费试用!

欢迎关注公众号:前端工匠,你的成长咱们一块儿见证!若是你感受有收获,欢迎给我打赏,以激励我更多输出优质开源内容

参考文章

相关文章
相关标签/搜索