【网络】计算机网络笔记——QUIC 协议笔记

QUIC (Quick UDP Internet Connections)协议是一个由 Google 推出的一款基于 UDP 实现的高效、可靠的网络协议,它基于 UDP 实现了一系列可靠的机制从而使得它兼顾了高效与可靠两大特点。

根据官方对它的描述,它是一个减少了 TCP 协议所存在的延迟的协议。表面上看 QUIC 就像是基于 UDP 实现的 TCP + TLS + HTTP/2.0 的结合体:

QUIC is a new transport which reduces latency compared to that of TCP. On the surface, QUIC is very similar to TCP+TLS+HTTP/2 implemented on UDP.

我们都知道 HTTP/2.0 实际上是 HTTP over SPDY,而即将到来的 HTTP/3.0,实际上就将被称为 HTTP over QUIC,甚至有人调侃道 QUIC 简直就是 TCP/2,这也侧面证明了 QUIC 的优越性。

为什么选择 UDP

TCP 协议看似完美,并且已经在 HTTP 协议之下应用了非常久,但它实际上是存在很多问题的,这也是 HTTP/2 目前面临的瓶颈之所在:

  • 网络环境的不适应:TCP 协议在网络流行的早期推出,因为那时的网络不像如今这样发达,丢包率十分之高,因此非常迫切地需要一款协议来保证数据的可靠传输。但如今的网络环境已经与当年大不相同了,相对来说非常的可靠,对于 TCP 中的一部分通过性能的损耗而保证可靠性的机制,对我们来说不再是必要的,我们更需要网络协议能带来更高的性能。
  • TCP 的更新成本过高:TCP 协议中的一些对网络的优化其实并不是最优解,在目前的角度看来实际上仍有优化的空间。但如果要修改 TCP 协议,它的代价非常之大,因为它的实现往往存在于操作系统的内核中,要对它进行修改意味着需要依赖操作系统内核的更新。

基于以上的原因,Google 不再选择对 TCP 进行优化,而是另辟蹊径,选择了 UDP 作为其运输层协议,基于 UDP 搭建一套与 TCP 功能相近但又进行了大量优化的 QUIC 协议。它的实现存在于应用层,因此会更利于未来的更新与迭代。

相比 HTTPS 的优势

QUIC 协议相比 HTTPS(TCP+TLS+HTTP/2)这样的组合,有着如下的优势:

  1. 减少了 TCP 的三次握手以及 TLS 握手的时间。
  2. 对 HTTP/2 对多路复用进行了改进。
  3. 对拥塞控制机制进行了改进。
  4. RTT 计算更为精准。
  5. 加密认证程度更高,相比 HTTPS 更安全。
  6. 引入了前向纠错机制。
  7. 连接迁移机制。

连接建立

QUIC 协议相比 HTTPS 来说大大减少了连接建立的时延,它可以实现 0RTT 的连接建立,在 0RTT 内就可以完成运输层的连接建立以及加密层的加密连接建立,只需要进行一次 QUIC 连接建立即可,并且连接建立的过程中可以同时进行数据的传输。

QUIC 的 0RTT 的握手是基于 UDP 的基础上,实现了 0RTT 的安全握手,从而达到的 0RTT 握手。

拥塞控制

QUIC 的拥塞控制包含了 TCP 中的四个算法:慢启动、拥塞避免、快速重传、快速恢复。它默认使用了这些算法,同时又对 BBR 等拥塞控制算法进行了支持。

QUIC 最大的优化不在于拥塞控制算法本身,而是由于它是在应用层的,因此它的拥塞控制是可插拔的,可以由应用程序实现不同的拥塞控制算法,并不需要操作系统的支持,并且拥塞控制算法可以灵活地进行配置,对于不同的连接采用不同的拥塞控制算法。

多路复用

QUIC 对 HTTP/2 的多路复用进行了改进,我们先了解一下 HTTP/2 的多路复用存在怎样的问题:

如图,这是 HTTP/2 的多路复用机制的实现,由于是通过复用同一条 TCP 连接,通过分帧的形式将 R、G、B 三个请求同时进行传输,因此它们是通过同一条 TCP 连接进行传输。

根据 TCP 的特性,它们三个会按序进行确认,比如此时如果 R 请求出现了丢包,那么会导致如下的情况:

可见,R 出现了丢包,导致 TCP 不会接收后面的 G、B 数据,从而使得 G、B 的传输也受到了影响。

因此 HTTP/2 的多路复用没有将多个请求的数据传输进行分离,它们都是通过同一条 TCP 连接进行传输,互相之间会相互影响

QUIC 协议则避开了 TCP,它引入了 Stream 的概念,一条 QUIC 连接可以复用多条 Stream,这些 Stream 互相独立,因此即使 R Stream的数据出现了丢包,也不会对 G、B 这两条 Stream 的传输造成影响:

我们可以将 QUIC 连接看作是原来的 TCP 连接,而一个 Stream 则对应了一个 HTTP 请求

流量控制

QUIC 的流量控制就是基于前面的 QUIC 连接以及 Stream 实现的:

通过 window_update 帧可以告诉对方自己收到的字节数,发送方就会对自己能够发送的字节数进行限制。

而通过 block 帧可以告诉对方由于流量控制被阻塞,无法发送数据。

由于 TCP 采用累积确认,因此其发送窗口的右滑长度取决于已确认的字节数。若出现了丢包,即使收到更大的报文段也不会向右滑。

而 QUIC 由于没采用累积确认,因此它的窗口右滑只取决于收到的确认字节数。

对于每条 Stream:

可用窗口大小 = 最大窗口大小 - 已收到的最大数量(读取+收到未读取)

对于每个 QUIC 连接:

可用窗口大小 = 可用窗口1 + 可用窗口2 + 可用窗口N

并且可以发现,我们其实可以对不同的 Stream 设置不同的窗口大小。

RTT 计算的优化

对于 RTT 计算,QUIC 进行了一些优化,解决了 TCP 中的 RTT 计算不精确的问题。

PacketNumber

在 TCP 中,报文中包含了序列号,而在 QUIC 中则采用了 PacketNumber 替代序列号,它们都表示了一个数据报文的编号,但仍然有一定区别。

TCP 协议中如果丢包导致了重传,这个重传的报文也会采用与丢包的报文同样的编号,而对于 QUIC 协议,这个 PacketNumber 是递增的,即使重传采用的也是大于该原来编号的新的 PacketNumber。

通过这样单调递增的 PacketNumber,解决了 TCP 重传存在的 RTT 计算歧义问题:

可以看到,上面左边的图片,如果以原始请求到收到 ACK 来计算 RTT,显然是大了,但它在右图这种情况中计算的 RTT 才是正确的。

而在上面左图的情况如果以重传请求开始到收到 ACK 计算 RTT,左图的计算是正确的,但对于右图来说又小了。

因此 TCP 这种重传采用同样的序列号会导致 RTT 计算的不正确,QUIC 通过重传采用了不同的 Packet Number 解决了这个问题。

由于重传报文与原报文的 PacketNumber 也不同,因此确认号也不同,从而使得发送方能够辨别究竟是原始请求的 ACK 还是重传请求的 ACK。

ACK 延迟问题

对于 TCP 的 RTT 计算,它只考虑了接收 ACK 的时间与发出报文的时间之差,也就是说:

RTT = ackTime - sendTime

但我们知道 TCP 实际上存在一种 ACK 延迟机制,它并没有考虑 ACK 延迟机制所带来的时间延迟。显然,计算出来的 RTT 是偏长了的。

而对于 QUIC,它对 ACK 延迟造成的时间差进行了考虑从而使得 RTT 的时间计算更精准

RTT = ackTime - sendTime - ackDelay

有序性的保证

为了保证数据的有序性,QUIC 还引入了 Stream Offset。这个 Stream Offset 就是为了用来保证数据的有序性的。一个 Stream 可以由多个 Packet 进行传输,由于 PacketNumber 是单调递增的,无法表示次序,因此 QUIC 引入了 Stream Offet,通过 Offset 可以确定 Packet 的顺序,使得这个 Stream 的数据传输仍然能够按序到达。

可以看到,Stream Offset 为 x 的 Packet 进行了重发,虽然它重发的 Packet Number 并不同,但是由于 Stream Offset 是有序的,因此接收方可以根据这个 Stream Offset 将 Packet 的顺序重新组织起来。

加密认证

QUIC 协议的加密认证采用了如下的方式:

如图所示,上半的红色部分为 Stream 中传输的帧的头部信息,对它进行了认证。而下半的绿色部分为 Stream 帧的内容,它经过了加密。

连接迁移

对于一条 TCP 连接,根据前面 TCP 协议的文章可以看出,它可以由 [源 IP 地址、源端口号、目的 IP 地址、目的端口号] 这样一个四元组唯一标示。

这就意味着这个四元组中任何一个发生变化,都需要重新建立一条新的连接。

QUIC 为了解决这个问题,会以一个 64 位的随机数作为 ID 来唯一标识一条连接,这样只要这个随机数 ID 不变,这条连接就会依然维持,从而很方便的支持连接的迁移。

当然,提到随机大家肯定会想到冲突问题,但 64 位数冲突的概率实在是太小了,差不多是 1/2^64 的概率了。

参考资料

科普:QUIC协议原理分析

QUIC 简明教程

QUIC overview

QUIC, a multiplexed stream transport over UDP

Rogan_Quic_Next_Generation_v1.pdf

点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注

%d 博主赞过: