当前位置:   article > 正文

QUIC原理及使用_quic协议原理

quic协议原理

TCP协议存在的不足

        队头阻塞:这个问题是长连接面临的最严重问题,在弱网环境、丢包率较高的场景下,消息的延迟时间会非常大。其主要原因是,在我们正常的TCP连接请求中,由于TCP协议的可靠性和一致性保障,一个请求中某一个包的丢失,会导致后续已到达的数据包延迟交付给业务层,直到丢失包经过重传恢复。对于QUIC而言,由于其采用UDP,完全不会出现上面的问题,其带宽占用相对TCP而言会变多,以一定的带宽消耗提高消息的实时性是完全可行的。另外,相较于TCP的流量控制,QUIC在Connection和Stream两个级别分别进行流控

        连接迁移:TCP使用四元组 (源IP,源端口,目的IP,目的端口) 标识连接,网络切换时会导致重连,而 QUIC 使用自定义的Connection ID作为链接标识,只要客户端使用的ConnectionID不变,即使网络切换也能保证链接不中断,连接发生迁移后,拥塞控制清零重新计算。

        握手延迟:TCP三次握手需要 1 个RTT ,TCP握手完成后,才能进行TLS握手,TLS握手需要至少 2 个 RTT ,这样就需要 3 个RTT后,客户端才能给服务端发送请求。即使是优化后的TLS也需要 1 个RTT ,这种情况下需要2个RTT后,客户端才能给服务端发送请求。对于QUIC而言,QUIC总共只需要1个RTT就能完成握手,也就是说1个RTT后,客户端就可以将请求发送给服务端。另外,在QUIC连接复用的情况下,不需要进行再次握手,客户端可以直接发送请求给服务端,也就是常说的0RTT。

        QUIC在应用层即可实现不同的拥塞控制算法,不需要改操作系统和内核单个程序的不同连接也能支持配置不同的拥塞控制。这样我们就可以给不同的用户选择不同的拥塞控制,提高用户的体验。应用程序变更拥塞控制,甚至不需要停机和升级。QUIC还有带宽预测,RTT监控,发送速率调整等高级算法支持。

        综上,QUIC可以很好的解决TCP的队头阻塞、连接迁移、ACK Delay、0RTT等问题。

QUIC原理

        TCP 队头阻塞的主要原因是数据包超时确认或丢失阻塞了当前窗口向右滑动,我们最容易想到的解决队头阻塞的方案是不让超时确认或丢失的数据包将当前窗口阻塞在原地。QUIC (Quick UDP Internet Connections)也正是采用上述方案来解决TCP 队头阻塞问题的。

        TCP 为了保证可靠性,使用了基于字节序号的 Sequence Number 及 Ack 来确认消息的有序到达。QUIC 同样是一个可靠的协议,它使用 Packet Number 代替了 TCP 的 Sequence Number,并且每个 Packet Number 都严格递增,也就是说就算 Packet N 丢失了,重传的 Packet N 的 Packet Number 已经不是 N,而是一个比 N 大的值,比如Packet N+M。

        QUIC 使用的Packet Number 单调递增的设计,可以让数据包不再像TCP 那样必须有序确认,QUIC 支持乱序确认,当数据包Packet N 丢失后,只要有新的已接收数据包确认,当前窗口就会继续向右滑动。待发送端获知数据包Packet N 丢失后,会将需要重传的数据包放到待发送队列,重新编号比如数据包Packet N+M 后重新发送给接收端,对重传数据包的处理跟发送新的数据包类似,这样就不会因为丢包重传将当前窗口阻塞在原地,从而解决了队头阻塞问题。那么,既然重传数据包的Packet N+M 与丢失数据包的Packet N 编号并不一致,我们怎么确定这两个数据包的内容一样呢?

        还记得前篇博文:Web技术(五):HTTP/2 是如何解决HTTP/1.1 性能瓶颈的?_流云IoT的博客-CSDN博客使用Stream ID 来标识当前数据流属于哪个资源请求,这同时也是数据包多路复用传输到接收端后能正常组装的依据。重传的数据包Packet N+M 和丢失的数据包Packet N 单靠Stream ID 的比对一致仍然不能判断两个数据包内容一致,还需要再新增一个字段Stream Offset,标识当前数据包在当前Stream ID 中的字节偏移量。

        有了Stream Offset 字段信息,属于同一个Stream ID 的数据包也可以乱序传输了(HTTP/2 中仅靠Stream ID 标识,要求同属于一个Stream ID 的数据帧必须有序传输),通过两个数据包的Stream ID 与 Stream Offset 都一致,就说明这两个数据包的内容一致。

Stream Offset保证数据包有序性

         上图中数据包Packet N 丢失了,后面重传该数据包的编号为Packet N+2,丢失的数据包和重传的数据包Stream ID 与 Offset 都一致,说明这两个数据包的内容一致。这些数据包传输到接收端后,接收端能根据Stream ID 与 Offset 字段信息正确组装成完整的资源。

        QUIC 通过单向递增的Packet Number,配合Stream ID 与 Offset 字段信息,可以支持非连续确认应答Ack而不影响数据包的正确组装,摆脱了TCP 必须按顺序确认应答Ack 的限制(也即不能出现非连续的空位),解决了TCP 因某个数据包重传而阻塞后续所有待发送数据包的问题(也即队头阻塞问题)。

        QUIC 可以支持非连续的数据包确认应答Ack,自然也就要求每个数据包的确认应答Ack 都能返回给发送端(TCP 中间丢失几个Ack 对数据包的确认应答影响不大),发送端收到该数据包的确认应答后才会释放该数据包所占用的缓存资源,已发送但未收到确认应答的数据包会保存在缓存链表中等待可能的重传。QUIC 对确认应答Ack 丢失的容忍度比较低,自然对Ack 的传输能力进行了增强,Quic Ack Frame 可以同时提供 256 个 Ack Block,在丢包率比较高的网络下,更多的 Ack Block 可以提高Ack 送达的成功率,减少重传量。
        原文链接:https://blog.csdn.net/m0_37621078/article/details/106506532

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/626391
推荐阅读
  

闽ICP备14008679号