从HTTP2.0到QUIC

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_41594698/article/details/102079593

来源:

https://www.cnblogs.com/purpleraintear/p/6026085.html

《趣谈网络协议》

1 场景引入

假设有一个页面要发送三个独立的请求:一个获取css,一个获取js,一个获取图片.jpg

如果使用HTIP1.1,那么就是串行发送(如图的上侧,不考虑pipeline)

但如果使用HTTP 2.0,那么在一个连接里,客户端和服务端都可以同时发送多个请求或回应,而且不用按照顺序一对一对应(如图的下侧)
在这里插入图片描述
其实就是以将多个请求分到不同的流中,然后将请求内容拆成帧,进行二进制传输.这些帧可以打散顺序发送,然后根据每个帧首部的流标识符重新组装,并且可以根据优先级,决定优先处理哪个流的数据.

HTTP 2.0 成功解决了HTTP 1.1 的队首阻塞问题:严格串行的返回响应,它不允许多个数据交错到达,只能等待一个响应完全返回后,下一个响应才能发送,无论下一个响应是否早于前一个响应完成处理;
同时,也不需要通过HTTP 1.x 的pipeline机制用多条TCP 连接来实现并行请求与晌应,减少了TCP 连接数对服务器性能的影响;
同时将页面的多个数据css、js、jpg 等通过一个数据链接进行传输,能够加快页面组件的传输速度.

HTTP 2.0虽然大大增加了并发性,但还是有问题的.因为HTTP 2.0 也是基于TCP 协议的,TCP 协议在处理包时是有严格顺序的.当其中一个数据包遇到问题, TCP 连接需要等待这个包,完成重传之后才能继续进行.虽然HTTP
2.0 通过多个stream ,使得逻辐上一个TCP 连接上的并行内容,进行多路数据的传输,虽然这中间并没有关联的数据.一前一后,但是前面stream 2 的帧没有收到,后面stream 1 的帧也会因此阻塞.(意思是如果收到了stream 1,但是没有收到stream 2,则stream 1不能发送ack,不能交给应用层,这样发送方因为没有收到stream 1的ack,可能会超时重传,浪费带宽)

接下来看看QUIC这个自定义的基于UDP的协议是如何解决HTTP2.0的问题的

2 QUIC

基于UDP 自定义类似TCP 的连接、重试、多路复用、流量控制技术,进一步提高性能.

  • 机制一:自定义连接机制

一条TCP 连接是由四元组标识的,分剧是源IP、源端口、目的IP、目的端口.一旦一个元素发生变化时,就需要断开重连,重新连接.在移动互联情况下,当手机信号不稳定或者在WIFI 和移动网络切换时,都会导致重连,从而进行再次的三次握手,导致一定的时延.

扫描二维码关注公众号,回复: 7592015 查看本文章

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

  • 机制二:自定义重传机制

TCP 为了保证可靠性,通过使用序号和应答机制,来解决顺序问题和丢包问题.

任何一个序号的包发过去,都要在一定的时间内得到应答,否则一旦超时,就会重发这个序号的包,这个超时时间是通过采样往返时间RTT来不断调整的,这种超时的采样方法存在不准确的问题.例如,发送一个包,序号100,发现没有返回,于是再发送一个100,过一阵返回一个ACK101. 这个时候害户端知道这个包肯定收到了,但是往返时间是多少呢?是ACK 到达的时间减去后-个100 发送的时间,还是减去前一个100 发送的时间昵?事实是,第一种算法把时间算短了,第二种算法把时间算高了.(如下图左侧)

QUIC 也有个序列号,不过是递增的.任何一个序列号的包只发送一次,下次就要加1.
例如,发送一个序号是100的包,发现没有返回;再次发送的时候,序号就是101 了;如果返回的ACK100,就是对第一个包的响应.如果返回ACK 101 就是对第二个包的响应, RTT计算相对准确.

但愚这里存在一个问题,就患怎么知道包100 相包101 发送的是同样的内容呢?
QUIC 定义了一个offset的概念:
QUIC 既然是面向连接的,也就像TCP 一样,是一个数据流,发送的数据在这个数据流里面有个偏移量offset,可以通过offset仔细查看数据发送到了哪里,这样只要这个offset 的包没有来,就要重发;如果来了,按照offset拼接,还是能够拼成一个流.(如下图右侧)
在这里插入图片描述

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

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

同HITP 2.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 所能容纳的最大缓存,是真正的窗口大小,这样更加准确,不会浪费带宽(如图下侧)
在这里插入图片描述
另外,还有整个连接的窗口,需要对于所有的stream 的窗口做一个统计.

猜你喜欢

转载自blog.csdn.net/qq_41594698/article/details/102079593