解读 HTTP1/HTTP2/HTTP3

这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战html

HTTP/2 相比于 HTTP/1.1,能够说是大幅度提升了网页的性能,只须要升级到该协议就能够减小不少以前须要作的性能优化工做,虽然如此但HTTP/2并不是完美的,HTTP/3 就是为了解决 HTTP/2 所存在的一些问题而被推出来的。webpack

HTTP1.1 的缺陷

  1. 高延迟 — 队头阻塞(Head-Of-Line Blocking)
  2. 无状态特性 — 阻碍交互
  3. 明文传输 — 不安全性
  4. 不支持服务端推送

一、高延迟--带来页面加载速度的下降

虽然近年来网络带宽增加很是快,然而咱们却并无看到网络延迟有相应程度的下降。网络延迟问题主要因为队头阻塞(Head-Of-Line Blocking),致使带宽没法被充分利用web

队头阻塞是指当顺序发送的请求序列中的一个请求由于某种缘由被阻塞时,在后面排队的全部请求也一并被阻塞,会致使客户端迟迟收不到数据。针对队头阻塞,人们尝试过如下办法来解决:面试

  • 将同一页面的资源分散到不一样域名下,提高链接上限。 Chrome有个机制,对于同一个域名,默认容许同时创建 6 个 TCP持久链接,使用持久链接时,虽然能公用一个TCP管道,可是在一个管道中同一时刻只能处理一个请求,在当前的请求没有结束以前,其余的请求只能处于阻塞状态。另外若是在同一个域名下同时有10个请求发生,那么其中4个请求会进入排队等待状态,直至进行中的请求完成。
  • 合并小文件减小资源数。精灵图,Spriting合并多张小图为一张大图,再用JavaScript或者CSS将小图从新“切割”出来的技术。
  • 内联(Inlining)资源是另一种防止发送不少小图请求的技巧,将图片的原始数据嵌入在CSS文件里面的URL里,减小网络请求次数。
  • 减小请求数量。拼接(Concatenation)将多个体积较小的JavaScript使用webpack等工具打包成1个体积更大的JavaScript文件,但若是其中1个文件的改动就会致使大量数据被从新下载多个文件。

二、无状态特性--带来的巨大HTTP头部

无状态是指协议对于链接状态没有记忆能力。纯净的 HTTP 是没有 cookie 等机制的,每个链接都是一个新的链接。算法

因为报文Header通常会携带"User Agent""Cookie""Accept""Server"等许多固定的头字段(以下图),多达几百字节甚至上千字节,但Body却常常只有几十字节(好比GET请求、204/301/304响应),成了彻彻底底的“大头儿子”。Header里携带的内容过大,在必定程度上增长了传输的成本。更要命的是,请求响应报文里有大量字段值都是重复的,很是浪费。segmentfault

三、明文传输--带来的不安全性

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

四、不支持服务器推送消息

SPDY 协议与 HTTP/2 简介

一、SPDY 协议

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

image.png

HTTP/1.1有两个主要的缺点: 安全不足和性能不高,因为背负着 HTTP/1.x 庞大的历史包袱,因此协议的修改,兼容性是首要考虑的目标,不然就会破坏互联网上无数现有的资产。如上图所示,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的部署,使用HTTP/2能带来20%~60%的效率提高。

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

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

HTTP/2 新特性

一、二进制传输

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

它把TCP协议的部分特性挪到了应用层,把原来的"Header+Body"的消息"打散"为数个小片的二进制"帧"(Frame),用"HEADERS"帧存放头数据、"DATA"帧存放实体数据。HTP/2数据分帧后"Header+Body"的报文结构就彻底消失了,协议看到的只是一个个的"碎片"。

image.png

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

二、Header 压缩

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

具体来讲:

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

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

三、多路复用

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

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

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

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

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

  • 同个域名只须要占用一个 TCP 链接,使用一个链接并行发送多个请求和响应,这样整个页面资源的下载过程只须要一次慢启动,同时也避免了多个TCP链接竞争带宽所带来的问题。
  • 并行交错地发送多个请求/响应,请求/响应之间互不影响。
  • 在HTTP/2中,每一个请求均可以带一个31bit的优先值,0表示最高优先级, 数值越大优先级越低。有了这个优先值,客户端和服务器就能够在处理不一样的流时采起不一样的策略,以最优的方式发送流、消息和帧。

image.png

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

四、Server Push

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

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

image.png

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

五、提升安全性

出于兼容的考虑,HTTP/2延续了HTTP/1的“明文”特色,能够像之前同样使用明文传输数据,不强制使用加密通讯,不过格式仍是二进制,只是不须要解密。

但因为HTTPS已是大势所趋,并且主流的浏览器Chrome、Firefox等都公开宣布只支持加密的HTTP/2,因此“事实上”的HTTP/2是加密的。也就是说,互联网上一般所能见到的HTTP/2都是使用"https”协议名,跑在TLS上面。HTTP/2协议定义了两个字符串标识符:“h2"表示加密的HTTP/2,“h2c”表示明文的HTTP/2。

HTTP/2 的缺点

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

  1. TCP 以及 TCP+TLS 创建链接的延时
  2. TCP 的队头阻塞并无完全解决
  3. 多路复用致使服务器压力上升
  4. 多路复用容易 Timeout

建连延时

HTTP/2都是使用TCP协议来传输的,而若是使用HTTPS的话,还须要使用TLS协议进行安全传输,而使用TLS也须要一个握手过程,这样就须要有两个握手延迟过程

①在创建TCP链接的时候,须要和服务器进行三次握手来确认链接成功,即须要消耗完 1.5 个 RTT 以后才能进行数据传输。

②进行TLS链接,TLS有两个版本——TLS1.2和TLS1.3,每一个版本创建链接所花的时间不一样,大体是须要1~2个RTT。

总之,在传输数据以前,咱们须要花掉 3~4 个 RTT。

RTT(Round-Trip Time):
往返时延。表示从发送端发送数据开始,到发送端收到来自接收端的确认(接收端收到数据后便当即发送确认),总共经历的时延。

队头阻塞没有完全解决

上文咱们提到在HTTP/2中,多个请求是跑在一个TCP管道中的。但当出现了丢包时,HTTP/2 的表现反倒不如 HTTP/1 了。由于TCP为了保证可靠传输,有个特别的“丢包重传”机制,丢失的包必需要等待从新传输确认,HTTP/2出现丢包时,整个 TCP 都要开始等待重传,那么就会阻塞该TCP链接中的全部请求(以下图)。而对于 HTTP/1.1 来讲,能够开启多个 TCP 链接,出现这种状况反到只会影响其中一个链接,剩余的 TCP 链接还能够正常传输数据。

image.png

RTO:英文全称是 Retransmission TimeOut,即重传超时时间; RTO 是一个动态值,会根据网络的改变而改变。RTO 是根据给定链接的往返时间 RTT 计算出来的。 接收方返回的 ack 是但愿收到的下一组包的序列号。

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

多路复用致使服务器压力上升

多路复用没有限制同时请求数。请求的平均数量与往常相同,但实际会有许多请求的短暂爆发,致使瞬时 QPS 暴增。

多路复用容易 Timeout

大批量的请求同时发送,因为 HTTP2 链接内存在多个并行的流,而网络带宽和服务器资源有限,每一个流的资源会被稀释,虽然它们开始时间相差更短,但却均可能超时。

即便是使用 Nginx 这样的负载均衡器,想正确进行节流也可能很棘手。 其次,就算你向应用程序引入或调整排队机制,但一次能处理的链接也是有限的。若是对请求进行排队,还要注意在响应超时后丢弃请求,以免浪费没必要要的资源。引用

HTTP/3 新特性

一、HTTP/3简介

Google 在推SPDY的时候就已经意识到了这些问题,因而就另起炉灶搞了一个基于 UDP 协议的“QUIC”协议,让HTTP跑在QUIC上而不是TCP上。而这个“HTTP over QUIC”就是HTTP协议的下一个大版本,HTTP/3。它在HTTP/2的基础上又实现了质的飞跃,真正“完美”地解决了“队头阻塞”问题。

QUIC 虽然基于 UDP,可是在本来的基础上新增了不少功能,接下来咱们重点介绍几个QUIC新功能。不过HTTP/3目前还处于草案阶段,正式发布前可能会有变更,因此本文尽可能不涉及那些不稳定的细节。

二、QUIC新功能

上面咱们提到QUIC基于UDP,而UDP是“无链接”的,根本就不须要“握手”和“挥手”,因此就比TCP来得快。此外QUIC也实现了可靠传输,保证数据必定可以抵达目的地。它还引入了相似HTTP/2的“流”和“多路复用”,单个“流"是有序的,可能会由于丢包而阻塞,但其余“流”不会受到影响。具体来讲QUIC协议有如下特色:

  • 实现了相似TCP的流量控制、传输可靠性的功能

    虽然UDP不提供可靠性的传输,但QUIC在UDP的基础之上增长了一层来保证数据可靠性传输。它提供了数据包重传、拥塞控制以及其余一些TCP中存在的特性。

    QUIC 协议到底改进在哪些方面呢?主要有以下几点:

    1. 可插拔 — 应用程序层面就能实现不一样的拥塞控制算法。
    2. 单调递增的 Packet Number — 使用 Packet Number 代替了 TCP 的 seq。
    3. 不容许 Reneging — 一个 Packet 只要被 Ack,就认为它必定被正确接收。
    4. 前向纠错(FEC)
    5. 更多的 Ack 块和增长 Ack Delay 时间。
    6. 基于 stream 和 connection 级别的流量控制。
  • 实现了快速握手功能

    因为QUIC是基于UDP的,因此QUIC能够实现使用0-RTT或者1-RTT来创建链接,这意味着QUIC能够用最快的速度来发送和接收数据,这样能够大大提高首次打开页面的速度。0RTT 建连能够说是 QUIC 相比 HTTP2 最大的性能优点

  • 集成了TLS加密功能

    目前QUIC使用的是TLS1.3,相较于早期版本TLS1.3有更多的优势,其中最重要的一点是减小了握手所花费的RTT个数。

    在彻底握手状况下,须要 1-RTT 创建链接。 TLS1.3 恢复会话能够直接发送加密后的应用数据,不须要额外的 TLS 握手,也就是 0-RTT。

    可是 TLS1.3 也并不完美。TLS 1.3 的 0-RTT 没法保证前向安全性(Forward secrecy)。简单讲就是,若是当攻击者经过某种手段获取到了 Session Ticket Key,那么该攻击者能够解密之前的加密数据。

    要缓解该问题能够经过设置使得与 Session Ticket Key 相关的 DH 静态参数在短期内过时(通常几个小时)。

  • 多路复用,完全解决TCP中队头阻塞的问题

    和TCP不一样,QUIC实现了在同一物理链接上能够有多个独立的逻辑数据流(以下图)。实现了数据流的单独传输,就解决了TCP中队头阻塞的问题。

  • 链接迁移

    TCP 是按照 4 要素(客户端 IP、端口, 服务器 IP、端口)肯定一个链接的。而 QUIC 则是让客户端生成一个 Connection ID (64 位)来区别不一样链接。只要 Connection ID 不变,链接就不须要从新创建,即使是客户端的网络发生变化。因为迁移客户端继续使用相同的会话密钥来加密和解密数据包,QUIC 还提供了迁移客户端的自动加密验证。

总结

  • HTTP/1.1有两个主要的缺点:安全不足和性能不高。
  • HTTP/2彻底兼容HTTP/1,是“更安全的HTTP、更快的HTTPS",二进制传输、头部压缩、多路复用、服务器推送等技术能够充分利用带宽,下降延迟,从而大幅度提升上网体验;
  • QUIC 基于 UDP 实现,是 HTTP/3 中的底层支撑协议,该协议基于 UDP,又取了 TCP 中的精华,实现了即快又可靠的协议。

面试题 http2 与 http1.1 区别,了解 http3 么,说说;

答案嘛,既然看了本文,那就试着总结下吧,加深下记忆!!!

参考资料

  1. http2.0 原理详细分析
  2. HPACK: HTTP/2 里的沉默杀手
  3. QPACK:HTTP /3 的头压缩
  4. DH 算法
  5. 前向安全(ForwardSecrecy)
  6. TLS 1.3 VS TLS 1.2,让你明白 TLS 1.3 的强大
  7. CaddyWeb 服务器 QUIC 部署
  8. 关于 QUIC 的各类尝试
  9. 使用 QUIC 协议实现实时视频直播 0 卡顿
  10. 解密 HTTP/2 与 HTTP/3 的新特性
  11. Web通讯协议,你还须要知道: SPDY 和 QUIC
  12. 如何看待 HTTP/3 ?

若是这篇文章帮到了你,记得点赞👍收藏加关注哦😊,但愿点赞多多多多...

文中若有错误,欢迎在评论区指正

相关文章
相关标签/搜索