# 【NO.126】TCP将成为历史？看看谷歌的QUIC协议都做了些什么你就知道了

在过去几年中，QUIC已经成为谷歌服务网络通信的默认协议。正如这里所说的，QUIC现在被从Chrome浏览器到谷歌服务器的所有连接中的一半以上使用。它还得到了Microsoft Edge、Firefox和Opera的官方支持。

![img](https://pic2.zhimg.com/80/v2-5367efdcc38a220f8b239c1a7d46e3dd_720w.webp)

谷歌开发它时考虑到了网络安全，并用更先进和最新的技术取代了一些过时的标准。换句话说，QUIC可能代表着互联网的未来，这就是为什么理解它如此重要。

因此，让我们深入了解谷歌的QUIC协议，并介绍您需要了解的一切。

## **1.QUIC的历史**

> QUIC最初代表“快速UDP Internet连接”，尽管该术语不再用作首字母缩略词。现在，“QUIC”被用来描述谷歌设计的通用传输层网络协议。
> 2012年，最初开始实施和部署。
> 2013年，在IETF会议上，随着实验范围的扩大，它被公开宣布。
> 2015年6月，针对其规范的互联网草案提交给IETF进行标准化。
> 2016年，QUIC工作组成立。
> 2018年10月，QUIC上的HTTP映射开始被称为“HTTP/3”，使QUIC必然成为全球标准。
> 2021 5月，IETF最终在RFC 9000中对其进行了标准化。

## **2.什么是QUIC？**

> 谷歌的QUIC是一种基于UDP的低延迟互联网传输协议，该协议通常用于游戏、流媒体和VoIP服务。
> UDP比TCP轻得多，但反过来，它的纠错服务比TCP少得多。
> 通过QUIC，谷歌的目标是将UDP和TCP的一些最佳功能与现代安全工具相结合。-谷歌希望通过其QUIC协议加速网络

首先我们先来看看http协议，再带入到tcp，udp，quic，逐步探索。

## **3.HTTP 1：**

我们从HTTP/1.0开始，其中每个请求-响应对前面都是打开一个tcp连接，然后关闭同一个连接。这引入了大量延迟，并导致人们想出了一个名为keep-alive的解决方案，该解决方案在HTTP请求之间重用TCP连接，基本上延迟了连接的关闭。下面是有和没有keep alive的两个图表。

![img](https://pic1.zhimg.com/80/v2-06319b737a3b3a2e5ee9ae4748c4dfa0_720w.webp)

此示例还演示了在发出HTTP请求之前需要建立的TCP 3路握手。基本上，双方都使用序列号（SYN数据包）跟踪他们发送的内容。这样，如果他们丢失了任何数据包，就可以从最后一个序列号重新发送。请注意，作为每个连接建立的一部分，需要进行3路握手（SYN、SYN-ACK、ACK）。由于TCP是双向通信模式，因此需要在每个方向上发送ACK。FIN用于关闭TCP连接。

显而易见借助Keep-alive是一个很好的手段来保持连接。

仔细看，每个资源请求仍然需要在激发之前完成其先前的资源请求。例如，我不能发出索引请求。css在索引之前。html已返回。

嗯。他们是怎么解决的？

![img](https://pic1.zhimg.com/80/v2-631b5ce16c3b0ce1359371290608261c_720w.webp)

他们在HTTP/1.1中引入了一个名为pipeline流水线的特性。通过该特性，可以立即通过TCP连接发出每个HTTP请求，而无需等待前一个请求的响应返回。该图显示了HTTP/1.1.和pipeline。

报文的回复将以相同的顺序返回。这引入了一个称为HTTP线路头（HOL）阻塞的问题

## 4.什么是HOL？

> 假设您正在请求一个猫的图像和一个javascript文件。如果猫的图像太大，服务器在完成发送图像之前不会开始发送javascript文件。

是不是听起来很可怕，那么如何解决这一问题？

最初的方法是让浏览器打开最多6个到同一服务器的连接，作为性能优化，开发人员开始在多个域之间共享资源，以支持服务器上超过6个资源的情况。此外，这并没有解决为每个单独的连接设置TCP（和TLS）握手的开销。在第2部分之前，我不会讨论TLS。

这也引入了一些创新，如css ，减少了要通过网络传输的单个资源的数量。

很快人们意识到这是不可扩展的，于是引入了一种新的方法，即HTTP/2和多路复用。

本质上，它声明TCP连接上的每个HTTP请求都可以立即发出，而无需等待上一个响应返回。响应可以按任何顺序返回。下图再次说明了使用流的HTTP/1.1流水线和HTTP/2复用。注意在HTTP/2中使用多路复用流的视图。css在cat.png之前返回

![img](https://pic4.zhimg.com/80/v2-355a531bcabba89f9939f763089f62cf_720w.webp)

此外，与HTTP/1.1不同，在HTTP/1.1中，作为HTTP头的一部分的资源标识仅在一组tcp包的第一个tcp包中，在HTTP/2中，每个tcp包都包含资源的标识。这使得被拆分为多个TCP数据包的HTTP响应可以很容易地重新组合，消除了HTTP/1.1的串行性

是的，看起来我们已经最大限度地改进了HTTP/2多路复用

不完全是这样，这里还有一个缺陷，但您必须更深入地研究TCP堆栈。

## 5.**TCP，现在有什么缺陷？**

TCP是一种面向连接的协议。它会跟踪客户端和服务器之间传输的所有数据包，如果数据包在从服务器传输过程中丢失，它会将所有数据包保存在该数据包的序列号之后，直到丢失的数据包被重新发送，才将其传递给应用层。这里有一个图表来说明这一点。

![img](https://pic4.zhimg.com/80/v2-4fec9dd0ac0df8780db332c7539a31b7_720w.webp)

例如，在图中，如果数据包2来自视图。css丢失时，它会导致所有从3到20的数据包存储在接收缓冲区中，直到数据包2被重新发送后才传递到应用程序堆栈。尽管所有的包裹都来自猫。png将被接收，但底层TCP协议无法知道这一点，因此它强制重传。

（注意：这个图不是一个非常准确的表示，因为我已经从HTTP响应切换到了TCP响应来说明这个问题）。

如果你仔细观察它，潜在的问题是因为TCP的面向连接的本质。例如，如果TCP知道数据包1和数据包2是view.css的一部分，则只会导致数据包2重新传输，而不会阻止数据包3–20。标识HTTP/2层中底层多路复用流的流ID与底层TCP数据包ID断开连接。

## 6.QUIC与TCP

与TCP不同，QUIC协议只允许以加密形式进行通信。由于QUIC中未加密的通信形式被设计为禁止，因此隐私和安全是QUIC数据传输的固有部分。在网络安全方面，这无疑是一个优势，但在不严格要求加密的情况下，这也可能是一个无用的开销。

但与TCP+TLS相比，QUIC建立安全连接所需的时间代表了真正的突破。换句话说，QUIC的主要目标是大大减少连接设置期间的开销。

这得益于QUIC的设计。事实上，QUIC使交换配置密钥和支持的协议成为初始握手过程的一部分更快。具体而言，当发送方打开连接时，响应包还包括使用加密所需的未来数据包所需的数据。这一步骤不需要建立TCP连接，然后通过其他数据包协商安全协议。这会导致更高的连接速度和显著的响应降低，甚至在主机间重新连接期间降低到0ms，这被称为“零RTT连接建立”。

![img](https://pic1.zhimg.com/80/v2-03de8426d4a2736e8beb370d960e73f0_720w.webp)

正如您所看到的，典型的安全TCP连接需要两到三次往返，发送方才能真正开始接收数据。这可能需要300毫秒。而通过使用QUIC，发送者可以立即开始与之前已经交互过的接收者进行交互。

与UDP相比，QUIC是赢家，因为它具有UDP所不具备的拥塞控制和自动重传等TCP功能。这使得它本质上比纯UDP更可靠。详细地说，虽然QUIC使用UDP作为基础，但它涉及丢失恢复。这是因为QUIC的行为类似于TCP，它分别检查每个流，并在数据丢失时重新传输数据。

此外，如果一个流中发生错误，QUIC可以继续独立地为其他流提供服务。这一特性对于提高易出错链路的性能非常有用，因为在TCP注意到丢失或丢失的数据包之前，可能会收到大量额外的数据。在QUIC中，在修复流时，可以自由处理这些数据。

QUIC还提高了网络切换事件期间的性能，例如当移动设备用户从Wi-Fi网络移动到移动网络时。当在TCP上发生同样的事情时，将执行一个长过程，其中每个现有连接一次断开一个，然后按需重新建立。为了解决这个问题及其在性能方面的后果，QUIC包括到接收器的连接ID，而不考虑源。这允许简单地通过重新发送单个数据包来重新建立连接，该数据包始终包含该ID，即使发送方的IP地址发生了更改，接收方也会认为该ID有效。

## **7.那么，这是否足以让QUIC取代TCP？**

我知道一种叫做UDP的替代方案，它是无连接的。

但我们仍然需要联系，不是吗？我们如何在没有连接的情况下以可靠的方式请求资源（重新传输、确认、排序和整个沙邦）。我们需要一种方法来识别跨多个TCP数据包的资源。

如果我们删除TCP并使用IP上的流协议并将其与HTTP分层，该怎么办？该协议将像以前一样保持单个连接，但流将有自己的重传。实际上，每个流在一个更大的连接上都具有tcp特性。

这正是HTTP/3 到 QUIC所做的。QUIC作为TCP的替代品，在底层UDP数据包本身和HTTP/3之上维护流，而HTTP/2对流一无所知。将流视为小型TCP连接，但处于资源级别。换句话说，与HTTP相比，QUIC保留了单个资源流中的排序，但不再跨越单个流。这也意味着QUIC不再按照请求的顺序向应用程序层传递资源。

QUIC系统的另一个目标是提高网络切换事件期间的性能，例如当移动设备的用户从本地wifi热点移动到移动网络时发生的情况。当这种情况发生在TCP上时，会开始一个漫长的过程，每个现有连接都会逐一超时，然后根据需要重新建立。为了解决这个问题，QUIC包括一个连接标识符，该标识符唯一地标识到服务器的连接，而不考虑源。这允许通过发送始终包含此ID的数据包来重新建立连接，因为即使用户的IP地址发生更改，原始连接ID仍然有效。

指示客户端和服务器的速度的流控制保持在流级别。这是通过发布/订阅一个窗口来实现的，该窗口指示每一方可以发送多少数据，并在每次成功传输后更新该窗口。

为了在不等待重传的情况下从丢失的数据包中恢复，QUIC可以用FEC数据包补充一组数据包。与RAID-4非常类似，FEC数据包包含FEC组中数据包的奇偶校验。如果组中的一个分组丢失，则可以从FEC分组和组中的剩余分组中恢复该分组的内容。发送者可以决定是否发送FEC分组以优化特定场景（例如，请求的开始和结束）。

嗯。为什么我们需要UDP？为什么不通过IP实现QUIC？

这是因为企业和互联网上的大多数防火墙仍然支持UDP协议。如果我们要在IP上分层QUIC，我们必须重新配置所有这些。UDP无论如何都是一个小开销（8字节报头）。

QUIC的安全性问题呢？下次我们再来讨论

原文地址：https://zhuanlan.zhihu.com/p/592578434

作者：linux