HTTP1.0、HTTP1.1、HTTP2.0和HTTP3.0 QUIC的优缺点和进化路线

2020-03-05 10:19:40

http协议从http1.0,http1.1,http2.0到http3.0,每个版本的特点,改进了上个版本哪些问题,详解http协议的进化路线,拥抱QUIC。

1 HTTP1.0

1.0的HTTP版本,是一种无状态,无连接的应用层协议。 HTTP1.0规定浏览器和服务器保持短暂的链接。

浏览器每次请求都需要与服务器建立一个TCP连接,服务器处理完成以后立即断开TCP连接(无连接),服务器不跟踪也每个客户单,也不记录过去的请求(无状态)。

这种无状态性可以借助cookie/session机制来做身份认证和状态记录。

1.1 HTTP1.0存在的问题1:无法复用连接

每次发送请求,都需要进行一次TCP连接,而TCP的连接释放过程又是比较费事的。这种无连接的特性会使得网络的利用率变低。

1.2 HTTP1.0存在的问题2:队头阻塞(head of line blocking)

由于HTTP1.0规定下一个请求必须在前一个请求响应到达之前才能发送,假设前一个请求响应一直不到达,那么下一个请求就不发送,后面的请求就阻塞了。


2 HTTP1.1

HTTP1.1继承了HTTP1.0的简单,克服了HTTP1.0性能上的问题。

2.1 长连接

HTTP1.1增加Connection字段,通过设置Keep-Alive保持HTTP连接不断卡。避免每次客户端与服务器请求都要重复建立释放建立TCP连接。提高了网络的利用率。

如果客户端想关闭HTTP连接,可以在请求头中携带Connection:false来告知服务器关闭请求。

2.2 管道化(pipelining)——尴尬的假并行传输

HTTP1.1支持请求管道化(pipelining)。

基于HTTP1.1的长连接,使得请求管线化成为可能。 管线化使得请求能够“并行”传输

例如:

假如响应的主体是一个html页面,页面中包含了很多img,这个时候keep-alive就了很大作用。能够“并行”发送多个请求。(注意,这里的“并行”并不是真正意义上的并行传输

需要注意的是:服务器必须按照客户端请求的先后顺序依次回送相应的结果,以保证客户端能够区分出每次请求的响应内容。

也就是说,HTTP管道化可以让我们把先进先出队列从客户端(请求队列)迁移到服务端(响应队列)

如果所示,客户端同时发了两个请求分别获取html和css,假如说服务器的css资源先准备就绪,服务器也会先发送html,再发送css。

换句话来说,只有等到html响应的资源完全传输完毕后,css响应的资源才开始传输,不允许同时存在两个并行的响应。

可见,HTTP1.1还是无法解决队头阻塞(head of line blocking)的问题。同时“管道化”技术存在各种各样的问题,所以很多浏览器要么根本不支持它,要么直接默认关闭,并且开启的条件很苛刻……而且好像实际也没有什么用处。

2.3 HTTP1.1下的真并行传输——浏览器优化策略

HTTP1.1支持管道化,但是服务器也必须进行逐个响应的送回,这个是很大的一个缺陷。实际上,现阶段的浏览器厂商采取了另外一种做法,它允许我们打开多个TCP的会话,也就是说,上图我们看到的并行,其实是不同的TCP连接上的HTTP请求和相应。这才是真正的并行!

很多人以为的连接数情况:

各浏览器在HTTP1.0和HTTP1.1协议下支持的同一域名并行链接数量表格 各浏览器在HTTP1.0和HTTP1.1协议下支持的同一域名并行链接数量大小占比图

2.4 缓存处理——强缓存、协商缓存,启发式缓存(新增)

此外,HTTP1.1还加入了缓存处理(强缓存和协商缓存),新的字段如cache-control,支持断点传输,以及增加了Host字段(使得一个服务器能够用来创建多个Web站点)


3 HTTP2.0

HTTP2.0新特性如下:

3.1 二进制分帧

HTTP2.0通过在应用层和传输层之间增加一个二进制分层帧,突破了HTTP1.1的性能限制,改进传输性能。

3.2 多路复用(链接共享)——真并行传输


      流(stream):已建立连接上的双向字节流。

      消息:与逻辑消息对应的完整的一系列数据帧。

      帧(frame):HTTP2.0通信的最小单位,每个帧包含头部,至少也会标识出当前所属的流(stream_id)


所有HTTP2.0通信都在一个TCP链接上完成,这个链接可以撑在任意流量的双向数据流。

每个数据流以消息的形式发送,而消息由一或多个帧组成。这些帧可以乱序发送,然后再根据每个帧头部的流标识符(Stream_id)重新封装。

多路复用(连接共享)可能会导致关键字被阻塞,HTTP2.0里每个数据流都可以设置优先级和依赖,优先级高的数据流会被服务器优先处理和返回客户端,数据流还可以依赖其他的子数据流。

可见,HTTP2.0实现了真正的并行传输,它能够在一个TCP上进行任意数量的HTTP请求。而这个强大的功能基于“二级制分帧”的特性。

3.3 头部压缩

在HTTP1.X中,头部元数据都是以纯文本的形式发送的,通常会给每个请求增加500-8000字节的负荷。

比如cookie,默认情况下,浏览器会在每次请求的时候,把cookie附在header上面发给服务器。

HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header_files表,既避免重复header的传输,又减少了需要传输的大小。

高效的压缩算法可以很大的压缩header,减少发送包的数量从而降低延迟。

3.4 服务器推送

服务器除了最初请求的响应外,服务器还可以额外向客户端推送资源,而无需客户端明确的需求。


引申问题:HTTP1.1的合并请求(如CSSsprites)是否适用于HTTP2.0

没有必要。

在头部压缩技术总,客户端和服务器均会维护两份相同的静态字典动态字典

在静态字典中,包含了常见的头部名称与值的组合。静态字典在首次请求时可以使用。那么现在头部的字段就可以被简写成静态字典中相应字段的index。

而动态字典跟连接的上下文相关,每个HTTP/2连接维护的动态字典不尽相同。动态字典可以在连接不停地进行更新。

也就是说,原本完整的HTTP报文头部的键值或字段,由于字典的存在,现在可以转换成索引index,在相应的端再进行查找还原,也就起到了压缩的作用。

所以,同一个链接上产生的请求和响应越多,动态字典累积得越全,头部压缩的效果也就越好,所以针对HTTP/2网站,最佳实践是不要合并资源

另外,HTTP2.0多路复用,使得请求可以并行传输,而HTTP1.1合并请求的一个原因也是为了防止过多的HTTP请求带来的阻塞问题。而现在HTTP2.0已经能够并行传输了,所以合并请求也就没有必要了。


4 HTTP3.0

为什么要有HTTP3.0:HTTP/2底层TCP的局限带来的问题

由于HTTP/2使用了多路复用,一般来说,同一个域名下只需要使用一个TCP链接,但当这个连接中出现了丢包的情况,就会导致HTTP/2的表现情况反倒不如HTTP/2了。

原因是:

在出现丢包的额情况下,整个TCP都要开始等待重传,导致后面的所有数据都被阻塞。

但是对于HTTP/1.1来说,可以开启多个TCP连接,出现这种情况只会影响其中一个连接,剩余的TCP链接还可以正常传输数据。

由于修改TCP协议是不可能完成的任务。

Google搞了一个基于UDP协议的QUIC协议,并且使用在了HTTP/3上, HTTP/3之前的名称为HTTP-over-QUIC。

早期Quic协议,存在IETF和Google两个版本,直到它被证实命名为HTTP3.0:

>IETF的QUIC工作小组创造了QUIC传输协议。QUIC是一个使用UDP来替代TCP的协议。最初的时候,Google开始助力QUIC,其后QUIC更多地被叫做“HTTP/2-encrypted-over-UDP “。 >社区中的人们已经使用非正式名称如iQUIC和gQUIC来指代这些不同版本的协议,以将QUIC协议与IETF和Google分开(因为它们在细节上差异很大)。通过“iQUIC”发送HTTP的协议被称为“HQ”(HTTP-over-QUIC)很长一段时间。 >2018年11月7日,Litespeed的Dmitri宣布他们和Facebook已经成功地完成了两个HTTP/3实现之间的第一次互操作。Mike Bihop在该主题的HTTPBIS会话中的后续介绍可以在这里看到。会议结束时达成共识称新名称是HTTP/3!

4.1 0-RTT——QUIC协议相比HTTP2.0的最大优势

缓存当前会话的上下文,下次恢复会话的时候,只需要将之前的缓存传递给服务器,验证通过,就可以进行传输了。

0-RTT建连可以说是QUIC相比HTTP2最大的性能优势。

什么是0-RTT建连?

>传输层0-RTT就能建立连接 >加密层0-RTT就能建立加密连接

4.2 多路复用

QUIC基于UDP,一个连接上的多个stream之间没有依赖,即使丢包,只需要重发丢失的包即可,不需要重传整个连接。

4.3 更好的移动端表现

QUIC在移动端的表现比TCP好,因为TCP是基于IP识别连接,而QUIC是通过ID识别链接。

无论网络环境如何变化,只要ID不便,就能迅速重新连上。

4.4 加密认证的根文——武装到牙齿

TCP协议头没有经过任何加密和认证,在传输过程中很容易被中间网络设备篡改、注入和窃听。

QUIC的packet可以说武装到了牙齿,除了个别报文,比如PUBLIC_RESET和CHLO,所有报文头部都是经过认证的,报文Body都是经过加密的。

所以只要对 QUIC 做任何更改,接收端都能及时发现,有效地降低了安全风险。

4.5 向前纠错机制

QUIC协议有一个非常独特的特性,成为向前纠错(Foward Error Connec,FEC),每个数据包除了它本身的内容之外还包括了其他数据包的数据,因此少量的丢包可以通过其他包的冗余数据直接组装而无需重传。

向前纠错牺牲了每个数据包可以发送数据的上限,但是带来的提升大于丢包导致的数据重传,因为数据重传将会消耗更多的时间(包括确认数据包丢失,请求重传,等待新数据包等步骤的时间消耗)。

例如:

我总共发送三个包,协议会算出这个三个包的异或值并单独发出一个校验包,也就是总共发出了四个包。

当其中出现了非校验包丢失的情况,可以通过另外三个包计算出丢失的数据包的内容。

当然这种技术只能使用在丢失一个包的情况下,如果出现丢失多个包,就不能使用纠错机制了,只能使用重传的方式了。


引申问题:如何在Chrome中启用 QUIC 协议

MTF在资源服务器和内容分发节点都已经启用了 HTTP3.0 协议,根据 用户浏览器 向下兼容,强烈建议您在Chrome浏览器开启实验性QUICK协议支持,体验加速效果:

① 在浏览器地址栏:输入chrome://flags

② 找到Experimental QUIC protocol,将Default改为Enabled

在Google Chrome canary中开启实验性QUIC协议的方法


5 总结

HTTP1.0

无状态,无连接

HTTP1.1

持久连接

请求管道化

增加缓存处理(新的字段如cache-control)

增加Host字段,支持断点传输等

HTTP2.0

二进制分帧

多路复用(或连接共享)

头部压缩

服务器推送(Sever push)

HTTP3.0

基于UDP实现

0RTT建连

基于UDP的多路复用

加密认证的报文

向前纠错机制


本文整理于 腾讯NEXT学院课程,连接数图片来自ieFans.net,课程讲解非常详细。

https://ke.qq.com/course/198477?saleToken=1992883&from=pclink

Web前端从小白到大师完整课程邀请图

https://m.ke.qq.com/course/198477?saleToken=1992883&from=wxso


本文很长,感谢您的阅读,如果你对本文中关于HTTP协议的介绍有建议和补充,请通过下方的评论告诉我,我会及时修正,感谢!


115210
小宇
ShopXO插件 ▶力扣 ▶Github ▶M站