http1.1、http2.0和http3.0的演进

首页 linux http1.1、http2.0和http3.0的演进

http1.1

http1.1的优点

  • 1. 简单

HTTP 基本的报文格式就是 header + body,头部信息也是 key-value 简单文本的形式,易于理解,降低了学习和使用的门槛。

  • 2. 灵活和易于扩展

HTTP 协议里的各类请求方法、URI/URL、状态码、头字段等每个组成要求都没有被固定死,都允许开发人员自定义和扩充。

同时 HTTP 由于是工作在应用层( OSI 第七层),则它下层可以随意变化,比如:

  • HTTPS 就是在 HTTP 与 TCP 层之间增加了 SSL/TLS安全传输层;

  • HTTP/1.1 和 HTTP/2.0 传输协议使用的是 TCP 协议,而到了 HTTP/3.0 传输协议改用了 UDP 协议

  • 3. 应用广泛和跨平台

互联网发展至今,HTTP 的应用范围非常的广泛,从台式机的浏览器到手机上的各种 APP,从看新闻、刷贴吧到购物、理财、吃鸡,HTTP 的应用遍地开花,同时天然具有跨平台的优越性。

http1.1的缺点

缺点很明显


  1. 无状态双刃剑

无状态的好处,因为服务器不会去记忆 HTTP 的状态,所以不需要额外的资源来记录状态信息,这能减轻服务器的负担,能够把更多的 CPU 和内存用来对外提供服务。

无状态的坏处,既然服务器没有记忆能力,它在完成有关联性的操作时会非常麻烦。

对于无状态的问题,解法方案有很多种,其中比较简单的方式用 Cookie技术和Session技术,而Session又是基于Cookie实现的,这里不过多介绍俩张方案的实现。


  1. 明文传输

明文意味着在传输过程中的信息,是可方便阅读的,比如 Wireshark 抓包都可以直接肉眼查看,为我们调试工作带了极大的便利性。

这正是这样,HTTP 的所有信息都暴露在了光天化日下,相当于信息裸奔,也就是http传输非常不安全。


  1. 传输过程数据可能被篡改

由于数据没有进行加密,传输过程都是明文,则很有可能被中间站拦截并篡改,所以http无法证明报文的完整性,且容易被篡改。


  1. 无法验证通讯双方身份

不验证通信双方的身份,因此有可能遭遇伪装并劫持流量。

对于无状态这一点特点来说,不管是http1.1还是http2.0和http3.0都保持这一特点,因为这一特点并不是完全是一个缺点。

而对于明文传输保证不了报文的完整性无法验证双方身份的这3个缺点,https基本都解决啦,https是在应用层和传输层中间增加了一层SSL/TSL协议,https具体解决这3个问题的实现方式这里也不过多介绍。但是需要注意的一点是普通的https仅验证了服务端的身份(通过CA证书),其实并没有验证客户端的身份,所以有的https服务仍然可以通过抓包工具获取。

你可能也发现了,有的https服务可以被抓包,有的却抓不到,原因就是看https服务是否开启的双向验证,开始了双向验证之后不仅是在服务端需要按照证书,客户端也需要安装证书,也就是只有开启了双向验证的https来可以验证双方身份,且无法被抓到工具获取

http1.1的性能如何

HTTP 协议是基于 TCP/IP,并且使用了「请求 - 应答」的通信模式,所以性能的关键就在这两点里。

「请求 - 应答」的通信模式是在同一个TCP连接里客户端发出一个请求之后只能等待该请求被响应之后,客户端才可以发生下一个请求,如果上个请求一直没有被响应,那么就是会被阻塞,可以发现http的性能的关键就在于此。


  1. 长链接

早期 HTTP/1.0 性能上的一个很大的问题,那就是每发起一个请求,都要新建一次 TCP 连接(三次握手),请求完成后,都要断开TCP链接(4次挥手),俗称短链接,而且是串行请求,做了无谓的 TCP 连接建立和断开,增加了很大的通信开销。

为了解决上述 TCP 连接问题,HTTP/1.1 提出了长连接的通信方式,也叫持久连接,且是http1.1的默认方式了。这种方式的好处在于减少了 TCP 连接的重复建立断开所造成的额外开销,减轻了服务器端的负载。

短连接的特点是:只有任意一方执行完代码或者任意一方显示的明确提出断开连接时则会断开链接。

长连接的特点是:双方代码执行完成后并不会断开链接,而只要任意一端显示的明确提出断开连接,才会进行4次挥手断开TCP连接。


  1. 管道传输

HTTP/1.1 默认采用了长连接的方式,这使得管道(pipeline)网络传输成为了可能。

即可在同一个 TCP 连接里面,客户端可以发起多个请求只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。

还记得开头说的「请求 - 应答」的通信模式吗?该模式下同一个tcp客户端只能同时发送一个请求,只有该请求被响应之后才可以发送下一个请求,这种模式对应http的性能影响很大,而管道传输其实就是想解决这样问题的,但是遗憾的是管道传输并没有本质上解决上述的问题,原因继续往下看。


  1. 队头阻塞

举例来说,客户端需要请求两个资源。以前的做法是,在同一个 TCP 连接里面,先发送 A 请求,然后等待服务器做出回应,收到后再发出 B 请求。那么,管道机制则是允许浏览器同时发出 A 请求和 B 请求,如下图:


但是服务器必须按照接收请求的顺序发送对这些管道化请求的响应。


如果服务端在处理 A 请求时耗时比较长,那么后续的请求的处理都会被阻塞住,这称为「队头堵塞」。所以管道传输只解决了请求队头阻塞而没有解决响应队头阻塞。也就是说管道传输其实很鸡肋,没什么卵用。

TIP:实际上 HTTP/1.1 管道化技术不是默认开启,而且浏览器基本都没有支持。

有没有想过为什么响应时必须按照请求的顺序返回呢?如果没有按照请求的顺序返回会发生什么情况呢?我举个🌰,如果没有按照请求顺序响应会发生什么结果:

如果有俩个请求a和b,请求a先到达服务器,但由于某种原因导致a的响应被阻塞,而请求b随后到达服务器并得到了及时的响应,那么返回的响应的顺序其实发生了颠倒

客户端可能会错误地将属于请求a和响应b关联,此时数据就会发生了错乱。这就导致客户端难以确定哪个请求对应哪个响应,从而引发数据错乱

这就是为什么要求响应和请求的顺序要一致,一致时就是可以顺序匹配请求和响应,将不会出现上述的数据错乱问题。

本质原因就是请求和响应不能一一对应而只能按照顺序来匹配,可以继续往下看,http2.0是怎么解决这个对应的问题的。

http2.0

可以发现http1.1的性能其实很一般,http2.0对其做了很多改进,使性能发生了质的提升。废话不多说,上图。



那 HTTP/2 相比 HTTP/1.1 性能上的改进:

  • 内置TLS协议。

  • 头部压缩:使用静态表、动态表和HPack实现。

  • 二进制格式:Header+Body都使用二进制传输。

  • 并发传输:使用Stream、fream实现,Stream是实现并发传输的关键。

  • 服务器主动推送资源。

头部压缩

HTTP 协议的报文是由「Header + Body」构成的,对于 Body 部分,HTTP/1.1协议可以使用头字段 「Content-Encoding」指定 Body 的压缩方式,比如用gzip 压缩,这样可以节约带宽,但报文中的另外一部分 Header,是没有针对它的优化手段。

HTTP/1.1 报文中 Header 部分存在的问题:

  • 含很多固定的字段,比如 Cookie、User Agent、Accept 等,这些字段加起来也高达几百字节甚至上千字节,所以有必要压缩

  • 大量的请求和响应的报文里有很多字段和字段值都是重复,这样会使得大量带宽被这些冗余的数据占用了,所以有必须要避免重复性

  • 字段是 ASCII 编码的,虽然易于人类观察,但效率低,所以有必要改成二进制编码

HTTP/2 对 Header 部分做了大改造,把以上的问题都解决了。

HTTP/2 没使用常见的 gzip 压缩方式来压缩头部,而是开发了HPACK 算法,HPACK 算法主要包含三个组成部分:

  • 静态字典

  • 动态字典

  • Huffman 编码(压缩算法)

客户端和服务器两端都会建立和维护「字典」,用长度较小的索引号表示重复的字符串,再用Huffman 编码压缩数据,可达到 50%~90% 的高压缩率。

静态字典

首先TCP连接建立后,客户端和服务端都会有一张静态字典,它是写入到 HTTP/2 框架里的,不会变化的,静态表里共有61 组,如下图:


表中的Index 表示索引(Key),Header Value表示索引对应的 Value,Header Name表示字段的名字,比如 Index 为 2 代表Header头中method: GET,Index 为 8 代表Header头中的状态码 Status :200。


你可能注意到,表中有的 Index 没有对应的 Header Value,这是因为这些 Value 并不是固定的而是变化的,这些 Value 都会经过 Huffman 编码后,才会发送出去,具体是怎么实现的呢?继续往下看:

我们来看个具体的例子,比如Header头中下面这个 server 头部字段,在 HTTP/1.1 的形式如下:



作者:PENG先森_晓宇
链接:https://www.jianshu.com/p/d3f8579d754d
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


 
32    2024-08-06 17:37:47