Http2.0的一些思考以及Http3.0的优势

http的协议的发展也是经过了一个比较漫长的阶段,从最初的只支持get请求和纯文本的返回内容,到现在的各种文件,超文本...的传输,http协议毫无疑问是越来越强大了,而且,在这种演变中一定会有许多大佬的智慧的结晶,所有学习这些不仅可以丰富我们的知识,还能在某种程度上丰富自己的思维!

本文着重于1.0,2.0,3.0的版本的差异以及一些深层的原因。先从2.0开始.

一,二进制分帧

先解释一下,就是将一条连接上所有传输的信息,分割为更小的消息和帧(消息则是由一个或者多个帧组成的),并对他们采用二进制格式编码。首部信息放在Headers帧中,而主体信息被封装在Data帧中。而且在每个帧的首部都有一个标识位。那么问题就来了。

1.为什么2.0可以对所有的内容进行二进制转换?

因为二进制分帧层是在应用层和传输层之间的中间层,所有的信息都会从中经过,进而可以转换。

2.为什要用二进制?

首先就是效率会更高,计算机最喜欢处理二进制数了。除此之外就是可以根据帧头部的八个位来定义额外的帧。除了数据帧和头部帧,实际上还有PING帧、SETTING帧、优先级帧等等,为之后的多路复用打上坚实的基础。

3.有什么其他的好处?

还可以在一个连接上实现双向数据流以及乱序发送。因为在,每一个帧上都有一个标记位。浏览器和服务端双方可以前期乱序接收消息和帧。接收完毕按照标记位的排列来拼接成一整条信息。所以,浏览器并行发送的请求,服务器可以并行返回,而不需要按照顺序返回。

二,多路复用

简单来说,多路复用技术也是可以并行发送请求,而且无需等待响应返回的一种技术。消除了不必要的延迟,减少页面的加载时间。

1.和1.0的长连接的区别在哪?

1.0默认开启长连接,也就是保持tcp的连接不中断,可以一直发送http请求。但是长连接只能发送串行的请求,也就是一问一答式的,如果前一个请求的响应没有被接收,那么第二个请求不会发送,就会造成阻塞。而多路复用就是在一条tcp连接上,请求可以并行发送,而无需等待前面的响应返回。

2.和1.0的管道的区别?

管道也可以并行发送请求,但是返回响应的顺序则必须是发送时候的顺序。例如,发送A,B,C三个请求,那么返回的顺序就是A,B,C哪怕A返回之前,B,C已经准备好,依然要等到A返回,也容易造成阻塞。

实际上,多路复用的基础就是二进制分帧,因为可以乱序发送和接收,所以就不必担心接收错误消息的问题,接收完毕直接拼接。

三,首部压缩

首部压缩实现的一个核心预设就是,在第一次请求之后,大部分的字段可以复用的。而且随着页面越来越复杂,同一个页面发出的请求会越来越多。如果头部不压缩的话,会造成很大的流量开销。

1.那么首部压缩的原理是什么呢?

支持http2.0的浏览器和服务器会维护一个相同的静态表和一个动态表,以及内置一个霍夫曼编码表。静态表存储的是常见的一些头部,和一些很常见的头部键值对,例如method:get以及cookie。动态表开始是空的,如果头部命中静态表中的名称,那么就回将这份键值对加入动态表中,例如cookie:xxxx。这样做的原因在于,请求或则响应头命中了静态或者动态表的时候,只需要一个字节就能表示,可想而知,这个字节就是一个地址,指向表中的数据。来张大佬的图或许更加清晰。

 而且像cookie对应的值可以由霍夫曼编码,来压缩体积。本质上,还是基于二进制分帧的数据转换。

2.如果静态和动态表中都没有相应的字段怎么办?

可以知道的是,键和值都是长度不确定的,所以两者都提倡采用霍夫曼编码,而且在帧流中,都是以01000000作为起始字节作为标识,这是一个“外来家伙”。添加到动态表中。

四.请求优先级

客户端可以在发出的Headers帧中包含优先次序信息来为流指定优先级。也可以专门在Priority帧来改变流的优先级。具体实现就,是每个流都可以带有一个31比特的优先值:0 表示最高优先级;2的31次方-1 表示最低优先级。而服务器则根据优先级作为交互数据的依据,在响应数据准备好之后,优先将最高优先级的帧发送给客户端。

1.高优先级的流一定得排在低优先级流的前面吗?

不一定。高优先级的流不是绝对先发出。因为强制的规定可能会造成阻塞:低优先级的流会等待高优先级的流。

2.常见的高优先级的流是哪些?

●优先级最高:主要的html

●优先级高:CSS文件

●优先级中:js文件

●优先级低:图片/视频

五.服务器推送

简单来说,服务器可以对一个客户端请求发送多个响应,例如,浏览器向服务端请求index.html,里面包含一张样式表和一张图片。传统的方法就是会向浏览器发送三次请求。而服务端推送,则可以在一次请求内将这三个文件全部发送给浏览器,减少了请求次数,提升了网页性能。下面是网上关于http2.0的性能提升的,比1.0里面的将资源内嵌到网页中都要高。

 

1.不同域之间可以推送吗?

不可以。服务端推送也是遵守同源策略。

2.服务端推送有什么弊端?

如果服务端推送的内容,浏览器有缓存的话,就会浪费带宽。避免的方法就是在服务端配置,只对第一次请求实现服务器的推送。

好了,至此Http2.0的优势可以说是比Http1.0进步了许多。可以看到,2.0里面的大部分功能都是建立在二进制分帧这个基础的技术上,所以或许这也是他被称作2.0的理由吧。但是问题来了,Http2.0就是无懈可击了吗?还有没有他无法解决或者回避解决的问题?答案是肯定的。接下来来到Http3.0的神奇世界,看一看降维打击。

Http3.0相对于Http2.0是一种脱胎换骨的改变!

大家都知道,http协议是应用层协议,都是建立在传输层之上的。我们也都知道传输层上面不只有TCP协议,还有另外一个强大的协议UDP协议,2.0和1.0都是基于TCP的,因此都会有TCP带来的硬伤以及局限性。而Http3.0则是建立在UDP的基础上。所以其与Http2.0之间有质的不同。

Google率先推出的QUIC(quick UDP Internet Connection)就是很好的实践。

 那么Http3.0具体有什么特性呢?

一,连接迁移

先阐述一下tcp里面的四元组,一条tcp的唯一性标识,是由源IP,源端口,目的IP,目的端口,四元组标识。源IP,源端口一般比较稳定,但是目的IP,目的端口会由于网络元素等原因发生改变,一旦改变,那么此条tcp连接就会断开。

由于QUIC基于UDP协议,所以一条UDP协议不再由四元组标识,而是以客户端随机产生的一个64位数字作为ID标识。只要ID不变,那么这条UDP就会存在,维持连接,上层业务逻辑就感受不到变化。

二,无队头阻塞

首先来看队头阻塞问题的的两层原因:

 我们知道,http2.0的多路复用正好解决了http层的队头阻塞,但是tcp的队头阻塞依然存在。因为当数据包超时确认或者丢失,会等待重传,因此会阻塞当前窗口向右滑动,造成阻塞。而QUIC是基于udp的,创新点在于QUIC依靠一个严格的单调递增的packet序列,一个数据包里面还会有streamID和streamoffset偏移量,即使中途发生丢包或者超时确认,后面的数据包不会等待,等到接收完之后根据ID和offset即可完成重新拼装,从而避免了这种问题。

三,自定义的拥塞控制

tcp协议是在传输层,默认存在于系统中,而QUIC在应用层,当想要依据实际情况来重定义拥塞算法的时候,QUIC显然更加灵活。Google提出了cubic和newreno提供了许多可供编程的接口。当然,和tcp一样,也是默认采用cubic算法。

那么tcp的拥塞怎么控制的呢?

这一块其实知识也挺多,简单来说就是,拥塞窗口前期会指数增加,直到到达一个阈值,然后就开始线性增加,直到出现超时事件,窗口大小到达最大值MAX。之后窗口调整为初始值,开始同样的增长,阈值减小为MAX/2。但是超时不一定是因为拥塞,也可能是因为丢包,那怎么办呢?如果从最初开始增加,那么显然会比较慢,等到发送方连续收到3个接收方发出的丢包ACK,直接让窗口大小等于阈值,再线性增长。这也有一个响亮的名字,快速恢复算法

四,前向安全和前向纠错

都说udp不太靠谱,但是Google给QUIC加上了这个机制:每发送一组数据之后,就对这组数据进行异或运算(效率高),并将结果也发送出去,那么接收方就有两份数据版本,可以对初始数据进行纠错和校验。以此保证了可靠性。

写了这么多,但是也只能说我个人的一些浅层的思考,就像react一样,这些知识都是先辈们历经好多年打造出来的东西,要想做到深层次的掌握肯定是需要透彻研究的,我也会努力继续研究学习,学习知识的同时也学习思考方法。

当然了http0.9协议虽然简陋,但是我觉得那才是真正的创新,真正的从零到一。

本期就到这里啦,如果有小伙伴发现错误或者逻辑不严谨的地方,烦请指正!共同进步!

  • 15
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值