HTTP3.0(QUIC的实现机制)

摘要:
对于同一个标头,只有索引表中的索引使用HTTP2.0协议发送到TCP连接,不需要通过http1使用多个TCP连接。x实现并行请求和响应的流水线机制;Jpg等通过数据链路传输。TCP协议以严格的顺序处理数据包。当其中一个数据包遇到问题时,在找到并重新发送数据包之前,TCP连接无法继续。这使得TCP连接上的逻辑并行内容。

回顾HTTP2.0

HTTP1.1在应用层以纯文本的形式进行通信,每次通信都要带完整的HTTP的头,而且不考虑pipeli模式的化,每次的过程总是像上面描述的那样一去一回。那样在实时性、并发想上都存在问题

头部压缩:HTTP2.0会对HTTP的头进行一定的压缩,将原来每次都要携带的大量key value在两端建立一个索引表,对相同的头只发送索引表中的索引

HTTP2.0协议将一个TCP的连接中,切分成多个流。每个流都有自己的ID,而且流可以是客户端发服务端,也可以是服务端发客户端,它其实只是一个虚拟的通道。流是有优先级的

HTTP2.0还将所有的传输信息分割为更小的信息和帧,并对它们采用二进制格式编码。常见的帧有Header帧,用于传输Header内容,并且会开启一个新的流,再就是Data帧,用来传输正文实体。多个Data帧属于一个流

通过这两种机制,http2.0的客户端可以将对个请求不同的流中,然后将请求内容拆成帧,进行二进制传输。这些真可以打散乱序发送,然后根据每个帧首部的流标识符重新组装,并且可以根据优先级,决定先处理那个流的数据

二进制传输就是以上

例子:

假设一个页面要发送三个独立的请求,一个获取css,一个获取js,一个获取图片jpg。如果使用HTTP1.1就是串行的,但是如果使用HTTP2.0,就可以在一个连接里,客户端和服务端都可以同时发送多个请求或回应,而且不用按照顺序一对一对应
image
http2.0成功解决了http1.1的队首阻塞问题,同时,也不需要通过http1.x的pipeline机制用多条tcp连接来实现并行请求和响应;减少了tcp连接数对服务器性能的影响,同时将页面的多个数据css,js,jpg等通过一个数据链接进行传输,能够加快页面组件的传输速度。

QUIC协议

HTTP2.0 也是基于TCP协议的,tcp协议在处理包时是有严格顺序的

当其中一个数据包遇到问题,TCP连接需要等待找个包完成重传之后才能继续进行,虽然HTTP2.0通过多个stream,使得逻辑上一个tcp连接上的并行内容,进行多路数据的传输,然而这中间没有关联的数据,一前一后,前面stream2的帧没有收到,后面stream1的帧也会因此堵塞

于是google的 QUIC协议从TCP切换到UDP

  • 机制一:自定义连接机制
    一条tcp连接是由四元组标识的,分别是源ip、源端口、目的端口,一旦一个元素发生变化时,就会断开重连,重新连接。在次进行三次握手,导致一定的延时

在TCP是没有办法的,但是基于UDP,就可以在QUIC自己的逻辑里面维护连接的机制,不再以四元组标识,而是以一个64
位的随机数作为ID来标识,而且UDP是无连接的,所以当ip或者端口变化的时候,只要ID不变,就不需要重新建立连接

  • 机制二:自定义重传机制
    tcp为了保证可靠性,通过使用序号和应答机制,来解决顺序问题和丢包问题

任何一个序号的包发过去,都要在一定的时间内得到应答,否则一旦超时,就会重发这个序号的包,通过自适应重传算法(通过采样往返时间RTT不断调整)

但是,在TCP里面超时的采样存在不准确的问题。例如发送一个包,序号100,发现没有返回,于是在发送一个100,过一阵返回ACK101.客户端收到了,但是往返的时间是多少,没法计算。是ACK到达的时候减去第一还是第二。

QUIC也有个序列号,是递增的,任何宇哥序列号的包只发送一次,下次就要加1,那样就计算可以准确了

但是有一个问题,就是怎么知道包100和包101发送的是同样的内容呢?quic定义了一个offset概念。QUIC既然是面向连接的,也就像TCP一样,是一个数据流,发送的数据在这个数据流里面有个偏移量offset,可以通过offset查看数据发送到了那里,这样只有这个offset的包没有来,就要重发。如果来了,按照offset拼接,还是能够拼成一个流。

image

  • 机制三: 无阻塞的多路复用

有了自定义的连接和重传机制,就可以解决上面HTTP2.0的多路复用问题

同HTTP2.0一样,同一条 QUIC连接上可以创建多个stream,来发送多个HTTP请求,但是,QUIC是基于UDP的,一个连接上的多个stream之间没有依赖。这样,假如stream2丢了一个UDP包,后面跟着stream3的一个UDP包,虽然stream2的那个包需要重新传,但是stream3的包无需等待,就可以发给用户。

  • 机制四:自定义流量控制

TCP的流量控制是通过滑动窗口协议。QUIC的流量控制也是通过window_update,来告诉对端它可以接受的字节数。但是QUIC的窗口是适应自己的多路复用机制的,不但在一个连接上控制窗口,还在一个连接中的每个steam控制窗口。

在TCP协议中,接收端的窗口的起始点是下一个要接收并且ACK的包,即便后来的包都到了,放在缓存里面,窗口也不能右移,因为TCP的ACK机制是基于序列号的累计应答,一旦ACK了一个序列号,就说明前面的都到了,所以是要前面的没到,后面的到了也不能ACK,就会导致后面的到了,也有可能超时重传,浪费带宽

QUIC的ACK是基于offset的,每个offset的包来了,进了缓存,就可以应答,应答后就不会重发,中间的空档会等待到来或者重发,而窗口的起始位置为当前收到的最大offset,从这个offset到当前的stream所能容纳的最大缓存,是真正的窗口的大小,显然,那样更加准确。
image

免责声明:文章转载自《HTTP3.0(QUIC的实现机制)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇linux虚拟机时间同步php 7.1 openssl_decrypt() 代替 mcrypt_module_open() 方法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

使用分布式锁时考虑哪些问题

工作中经常会遇到争抢共享资源的场景,比如用户抢购秒杀商品,如果不对商品库存进行保护,可能会造成超卖的情况。超卖现象在售卖火车票的场景下更加明显,两个人购买到同一天同一辆列车,相同座位的情况是不允许出现的。交易系统中的退款同样如此,由于网络延迟和重复提交极端时间差的情况下,可能会造成同一个用户重复的退款请求。以上无论是超卖,还是重复退款,都是没有对需要保护的...

iOS 开发中常见的错误日志处理

Outline如何获得crash日志如何解析crash日志如何分析crash日志     1. iOS策略相关     2. 常见错误标识     3. 代码bug一、如何获得crash日志当一个iOS应用程序崩溃时,系统会创建一份crash日志保存在设备上。这份crash日志记录着应用程序崩溃时的信息,通常包含着每个执行线程的栈调用信息(低内存闪退日志例...

TCP连接与关闭

1、建立连接协议(三次握手) (1)客户端发送一个带SYN标志的TCP报文到服务器。这是三次握手过程中的报文1。 (2) 服务器端回应客户端的,这是三次握手中的第2个报文,这个报文同时带ACK标志和SYN标志。因此它表示对刚才客户端SYN报文的回应;同时又标志SYN给客户端,询问客户端是否准备好进行数据通讯。 (3) 客户必须再次回应服务段一个ACK报文,...

adobe reader安装失败时的解决方法

1、现在adobe reader 的官方网站取消了免在线安装方式的安装包的下载,导致下载下来的安装包只有1M多,然后只能连接互联网进行安装。 很容易发生在安装过程中提示“安装失败”,其实是下载失败的情况。这种问题可能由于国际互联网“不稳定”,基本很难解决。 2、使用第三方的软件安装方式进行安装。类似于软件管家的方式进行安装,发现安装后使用几十秒均发生软件崩...

关于stm32 HardFault_Handler 异常的处理 死机

在系统开发的时候,出现了HardFault_Handler硬件异常,也就是死机,尤其是对于调用了os的一系统,程序量大,检测堆栈溢出,以及数组溢出等,找了半天发现什么都没有的情况下,估计想死的心都有了。如果有些程序开始的时候一切没有问题,但是运行几个小时候,会发现死机了,搞个几天下来估计蛋都碎了一地吧。。。一般来说运行操作系统  是以下几个问题 1.开始的...

【ZT】SQL实现多字段模糊匹配关键字查询

我们开发数据库应用时,常常需要用到模糊查询。如果同一个条件需要匹配很多字段怎么办呢?通常,程序员会每个字段都在SQL中“field like'%cond%'”一次。这样,SQL语句会长得惊人,碰上复杂一点的,甚至SQL语句会因为超长而被数据库拒绝执行。其实,这个问题只要动动脑 筋就很容易解决:首先,将要匹配相同条件的字段连起来(field1+field2+...