关于HTTP/1.1,HTTP/2和HTTP/3的区别与联系

HTTP/1.1

每当说起http/1.1就会想起以前叫外卖的方式,那个时候很多店都没有专门的外卖员,打电话叫外卖,老板那就会叫人送货来,但是这样的方式有一个很大的问题,店员总是忘记放筷子。于是,店员送完外卖以后,要再送别的东西,就必须再走一趟。如果想要再点一个鸡腿什么的,还必须等到店员回到店里,再送一趟。这种”一次一份“的方式就对应着HTTP/1.1的核心。
在这里插入图片描述
HTTP/1.1才是互联网的第一个真正意义的HTTP标准版本。为什么说一次一份是这里的核心呢?
因为你发送一个http请求的时候,是需要等收到HTTP响应,才可以再发送下一个HTTP请求
在这里插入图片描述
我们浏览一个网页的时候就只需要点一次鼠标,明显就是一次请求,其实一个网页一般都有多个文件组成,最基本的就是HTML,CSS,JS和图片文件。对于HTTP协议来说,我们打开一个网页,需要进行TCP三次握手,建立起了TCP连接,才正式进行请求。服务器会先发送HTML文件给我们,但其他文件不会发给我们,浏览器在收到HTML文件以后,根据HTML里的内容,再向服务器依次请求css,js等文件,整个过程都是浏览器在帮我们完成,所以用户的直接感受是只有一次请求。

在这里插入图片描述
如果在请求队伍里有一个文件没有收到,后面的文件也没办法接收了,这就会造成HTTP队头阻塞了。因为对于HTTP来说,一次一个请求响应。虽然对于HTTP/1.1来说,默认是持久连接的,也就是保持这个TCP连接,不需要对每个请求再来一轮TCP握手,请求和响应都可以放在同一个连接里面,但是只有一个连接肯定太慢了,连接太多又怕会造成DDos攻击,因此各家浏览器允许的持久连接数都不太相同,通常我们都会看到说,chrome默认的是同时6个连接,即使有多个连接还是有问题的,假设浏览器的其他连接的响应文件都收到了,就只有一个连接的文件还没有收到,刚好是一个会导致浏览器没法渲染的css文件,这就会造成HTTP队头阻塞了。
在这里插入图片描述
为了解决这个问题,其实HTTP/1.1里有个叫管线化的技术,意思就是单个连接可以发送多个请求,但是这里有个问题,虽然可以一次发送多个,但是响应的时候必须按照发送的顺序接收,先发到什么就得先收什么。这就造成很大的执行难度,网络情况很难预知。非常有可能第一个要收到的响应丢包了,然后第二个响应变成了第一个接收到的,所以我们比较难能看到有浏览器实际会用这个管线化技术。
在这里插入图片描述
在网络协议层面上解决不了这个问题,那么就会有很多黑科技出来了。比如说很多网站会把小图标全部做成单独的一张图片,请求的时候就只需要请求一个文件,而不是分开这么多的请求。然后再用Js或者css把小图标分布到网站的各个部分,这个就叫做精灵图或者雪碧图,确实减少了请求次数,但是对于开发者来说就很麻烦了。除此之外,Dzta URLs是另一种代替方案,比如说一张图片可以用base64进行编码,然后就可以以字符的形式写进HTML或者css里面,不需要单独一份图片文件,但是一般这个文件结果会超级长,很不方面代码的维护和管理。前面说到浏览器会限制同一连接的请求数,其实是限制每个域的连接数,因此网站就弄出多个域,使得浏览器可以同时下载这些资源。举个极端的例子,比方说网站有5张图片,那么就可以设置5个图片域名,这样浏览器就可以同时进行下载了,就不用等前面的资源下载后轮到下一个资源了,也就是域名分片。不用想这样做很可怕,开发的复杂度被硬生生的提高了。
在这里插入图片描述
为了减少请求,还有很多方法,比如把js和css合并,或者把css和js都整合到html里面。虽然大家都在绞尽脑汁的减少请求,但是后来越来越多的网站都需要上锁了,也就是HTTPS,不然像谷歌浏览器就会给你的网站提示不安全,对于http/1.1来说无疑是雪上加霜,因为原本进行通信前就要进行TCP三次握手,HTTPS里的TLS/1.2又要进行握手,握手后才可以进行加密通信。
在这里插入图片描述
虽然后来的TLS/1.3减少了来回的次数,但对于http/1.1来说,这一来一回的负担还是太重了,越多的来回就意味着越多的未知数,如果网络上有中间件炸了,容易造成丢包,结果还是可能会阻塞网页的渲染。

在这里插入图片描述
可是TCP除了三次握手的固定开销以外,还会有个慢启动,因为要进行拥塞控制,也就是说为了不造成网络拥堵,而且也不知道网络的实际情况,一开始只会发送较小量的TCP数据段,到了后面再慢慢增加,因此会导致新访问网页刷新速度较慢。除了TCP的各种开销以外,我们也不要忘记HTTP本身就会产生固定开销,请求和响应都是有各种首部的,而且大部分首部都是重复的,发完一次下一次还发,特别是cookie,每次都得发送,字符还特别长,再加上HTTP/1.1本身就是明文的,首部也没有进行压缩,使得大部分首部又累赘又臃肿,就像每次去办事的时候,对方都一定要求你携带一大堆证明材料,于是后来有了HTTP/2。

HTTP/2

HTTP/2像是外卖2.0,店家聘请了很多个专门的外卖员,假设现在一次性点了早餐,午餐,晚餐和宵夜,老板一点都不担心,因为有足够多的外卖店员,不用因为只有一个店员送外卖而烦恼。这里就对应HTTP/2.0的一大特点,多路复用。主要是解决HTTP/1.1对头阻塞的问题。可能会有人说多路复用很厉害,再也不用多个连接了,单个TCP连接就可以进行交错发送请求和响应,而且请求和响应之间不影响,这样说确实没错,但是却忽略了里头的重要细节.HTTP/2并不是单个文件就这样直接响应过去,请求和响应报文都被划分为各个不同的帧,这个帧可以分为首部帧和数据帧,其实就是把原来HTTP报文的首部和实体部分给拆分为两部分,所以原本的HTTP报文就不再是原来的报文了,而有点像数据链路层的帧,一开始我们并不需要去细细研究这里面的结构,最重要的是有个”流标识符“。
在这里插入图片描述
正因为有了这个流标识符,使得帧可以不用按照顺序抵达对方那里,因为你即使没有按照顺序,最终有这个流标识符就可以按照顺序进行组合,而且帧类型里还可以设置优先级,标注流的权重。听起来HTTP/2的多路复用很爽快的解决对头阻塞了对不?其实并没有。
在这里插入图片描述
HTTP/2还是有值得表扬的地方,之前的HTTP/1.1报文主体压缩,首部不压缩,HTTP/2这回就把首部也压缩了,不过这次是引入了叫HPACK的压缩算法,HPACK算法要求浏览器和服务器都保存一张静态只读的表,比方说经典的”HTTP/1.1 200 OK 起始行“,在HTTP/2里面就变成了”:status:200",从肉眼看只是少了3个字节,大家可能觉得没什么大不了,但因为是重复的首部,可以实现在二此请求和响应里面直接去掉。另外像cookie这样的首部,可以作为动态信息加入到动态表里,这样节省下来的资源更是客观的,再加上这个HTTP/2的帧并不是ASCII编码的报文,而是被提前转化为二进制的帧,解析起来更有效率,当前推出HTTP/2的时候,还有一个“逆天”的技术让很多吹捧,就是服务器推送。其实比较好理解,当浏览器进行请求的时候,服务器可以不像以往一样,等浏览器解析HTML时再一个一个响应,而是把浏览器后续可能需要的文件,一次性全部发送过去。看着很美好,但实际操作却很“骨感“,因为客户端有可能点错了网页,轻轻点了一下,你就给我重重一拳,让我多了这么多缓存,而且服务器推送也可能会造成DDos非对称攻击,因为这里存在一个明显的”杠杆“,因此服务器推送也隐含着安全性的问题,但实际上HTTP/2比HTTP/1.1要安全很多。首先是前面说到报文变为二进制的帧,对于人来说,可读性就差了很多,其次虽然没有说HTTP/2规定要用TSL加密,但如果用了HTTP/2还不用TSL加密就说不过去了,因为到了HTTP/2这个年代,还不用TSL,大牌浏览器都会提示”不安全“,而且HTTP/2的多路复用也已经减少了等待的时间,久而久之就变成HTTP/2必须用TSL了,看见HTTP/2就很好,但为什么2015年公布的HTTP/2,在2019年就冒出来个HTTP/3呢?要知道HTTP/1.1公布的时候是97年,从2到3的进程太快了吧,这里肯定有问题,其实HTTP/2只解决了HTTP层面的队头阻塞,要知道HTTP下面还有个传输层呢?而且HTTP是基于TCP的,HTTP/2的帧下来以后就要由TCP处理了,HTTP/2的帧下来以后就要由TCP处理了,TCP才不知道你帧里面的内容哪个和哪个是一起的,TCP还是按照自己的数据段来发送,如果有丢失的,还得重传,夸张的是,即使丢失的TCP数据段刚好是一行代码注释,也没办法,也得继续等待,这也就是TCP层面的队头阻塞。怎么办呢?比较好的办法就是把TCP也变成HTTP/2的帧那样,关键TCP协议是由操作系统内核实现的,除非让整个世界大部分的操作系统都进行一次革新的升级,那不知道要等到猴年马月了,于是就有了HTTP/3协议了。

HTTP/3

HTTP/3相当于外卖3.0,在APP上点外卖非常方便,不会因为打电话点餐导致的不顺畅,直接点了付款,APP上直接整合了多个步骤,而且现在道路也四通八达,外卖小哥骑车到哪里都不会阻塞,这里就对应着HTTP/3的一大核心–整合。虽然我们很难把TCP进行快速地升级并且广泛应用,但是HTTP/3把TCP和TLS的握手整合到一起了。但是HTTP/3把TCP和TLS的握手过程整合在一起了,直接减少了来回带来的开销,如果是恢复的会话,还可以不用握手,实现0-RTT。
在这里插入图片描述
但问题是TCP和TLS是两个协议呢?并不是说合并就合并,实际上为了能够让HTTP/3进行部署,只能选择传输层发UDP协议了,并且在基于UDP协议上新增一个协议,也就是QUIC,这个QUIC整合了TCP和TLS,使得HTTP/3默认就是要使用加密传输的,也可以不严谨地说是TCP/2.0,但不能说是UDP/2.0。
在这里插入图片描述
很多人觉得使用TCP就慢,使用UDP就快,所以QUIC快就是因为基于UDP的缘故,这种说法不太靠谱。QUIC其实是因为要能够广泛部署才只能用UDP的,但实际上的机制还是大部分采用TCP的,但QUIC必须要就解决TCP队头阻塞的问题,从应用性那边过来的数据会被封装成QUIC帧,这个QUIC帧和HTTP/2的帧很像,也是加了”流标识符“,但和HTTP/2不同的是,HTTP/3的应用层上并没有所谓的帧的概念,把数据帧移到了QUIC里面,相当于在传输层就有了数据帧,从源头就可以解决头阻塞的问题,实现多路复用。QUIC帧又再次被封装为QUIC数据包,QUIC数据包会加上一些信息,这里最重要的是加了Connection ID连接ID,如果网络发生全面改变,比如从Wifi突然转到4G网络,虽然IP地址发生改变,但是因为客户端和服务端都协商好了连接ID,因此可以用连接ID来识别为同一个连接,避免再次握手,这是QUIC其中一个速度快的原因。而且QUIC数据包会把里面的QUIC帧给加密了,也就是在TLS握手后,QUIC帧的内容被加密了,接着QUIC数据包会被UDP封装成数据段,UDP就会加上端口号,当我们选择HTTP/3通信的时候,QUIC就会像TCP那样开启连接,QUIC数据包就是在这连接通道里收发的。

蛋老师视频讲解

猜你喜欢

转载自blog.csdn.net/qq_40992225/article/details/127875955
今日推荐