从 QUIC 到 TCP:为何更多公司开始采用 QUIC?

引言

在过去的三十年里,HTTP(超文本传输协议)一直是互联网的支柱。我们可以通过 HTTP 浏览网页、下载文件、流式传输电影等。这一协议随着时间的推移已经得到了重大改进。

HTTP 协议是一个应用层协议,它基于 TCP(传输控制协议)工作。TCP 协议有若干限制,导致 Web 应用响应较慢。

谷歌开发了一种名为 QUIC 的颠覆性传输协议,以克服 TCP 的缺点。QUIC 几年前被标准化,并加入到了 IETF(互联网工程任务组)。

近几年来,采用 QUIC 的公司数量呈指数增长。大多数技术公司,如谷歌、Facebook、Pinterest 等,已经开始采用在传输层使用 QUIC 的 HTTP/3.0。这些公司已经看到了其网站在使用 HTTP/3.0 和 QUIC 后性能的显著提升。

让我们开始我们的旅程,了解 QUIC 将如何取代 TCP。我们首先将了解 TCP 和 UDP 的一些基本网络概念。之后,我们将回顾 HTTP 的发展历程,以及每个版本是如何克服前一版本的限制的。然后我们将看看 QUIC 是什么,以及它是如何工作的。我们将探讨为什么 QUIC 比 TCP 具有更高的性能。

TCP 和 UDP 是如何工作的?

TCP(传输控制协议)和 UDP(用户数据报协议)是传输层协议。这些协议管理着来自任何电子设备的网络数据包的流动。让我们详细了解这两种协议是如何工作的。

TCP

TCP 是一种基于连接的协议。客户端与服务器建立连接后发送数据。TCP 连接通过一种称为三次握手的机制建立。下图说明了三次握手过程:

alt

TCP 三次握手过程

该过程包括三个步骤:

  1. SYN - 客户端向服务器发送一个 SYN 数据包。
  2. ACK - 收到 SYN 后,服务器通过 ACK 数据包向客户端发送确认。
  3. SYN-ACK - 客户端收到服务器的 ACK 数据包后,最终通过 SYN-ACK 向服务器发送确认。

TCP 是一种有状态且可靠的协议。它保证了一台设备到另一台设备的所有数据包的传递。此外,它允许客户端和服务器使用同一个连接进行通信。

UDP

UDP 是一种无连接协议。与 TCP 不同,客户端与服务器之间没有三次握手。客户端发送数据包给服务器,不等待服务器的确认。

UDP 不保证 100% 的数据包传递。数据包可能会丢失,可能不会到达另一台设备。UDP 不像 TCP 那样可靠。

由于没有初始握手,UDP 比 TCP 快得多。出于性能考虑,UDP 主要用于流数据的应用,如音乐/视频。

TCP 与 UDP 对比模因

到目前为止,我们已经了解了 TCP 和 UDP 协议的工作原理。现在让我们探索 HTTP 协议,它是一个应用层协议。

HTTP 的发展历史

HTTP 的第一个版本是 1989 年由 Tim Berners-LeeCERN 开发的。从那时起,这个协议经历了多次优化和性能改进。大多数现代设备使用 HTTP 1.1/HTTP 2.0 和 HTTP 3.0。我们将回顾 HTTP 的历史,并了解该协议经历的主要变化。

HTTP/1.0

在最初的 HTTP/0.9 版本之后,HTTP/1.0 开始支持头部、请求体、txt 文件等。客户端每次从服务器获取数据时必须创建一个 TCP 连接。这导致了建立连接的资源大量浪费。

HTTP/1.1

此协议增加了在客户端和服务器之间重用现有 TCP 连接来获取新数据的支持。这是通过 HTTP 头 部的 keep-alive实现的。

如果客户端想要获取 10 个 Javascript 文件,则它会与服务器建立一次连接。然后,它会重用同一连接并获取这 10 个文件,而不是为每个文件创建一个新连接。

这减少了资源浪费并改善了性能,因为它避免了创建冗余连接。然而,一个主要的缺点是称为队头阻塞的问题。

alt

让我们通过一个例子来理解这个概念。如上图所示,你有三个文件——图片、文本和视频。视频文件的大小较大,传输所需时间更长。由于视频文件需要更长时间,它将阻止图像和文本文件的发送。

HTTP/2.0

HTTP 2.0 通过多路复用解决了 队头阻塞 问题。通过多路复用,多个文件可以通过同一个 TCP 连接发送。

alt

这结果提升了性能并在应用层解决了队头阻塞问题。然而,在 TCP 层面,如果发生数据包丢失,则必须等待数据包重传。

多路复用解决方案在数据包丢失的情况下并未像预期那样工作。事实上,如果数据包丢失超过 5%,HTTP 1.1 的表现会优于 HTTP 2.0。队头阻塞问题从应用层转移到了传输层。

下图说明了单个数据包丢失导致多个流延迟的情况:

alt

当一个数据包丢失时,TCP 会将后续数据包存储在其缓冲区中,直到收到丢失的数据包。然后,TCP 使用重传来获取丢失的数据包。HTTP 无法看到 TCP 的重传。因此,在这种情况下,不同的流会看到传输的延迟。

什么是 QUIC?

在过去的几节中,我们看到 TCP 有一些固有的限制,例如三次握手和队头阻塞。这些限制可以通过增强 TCP 或用新协议替换 TCP 来解决。

尽管增强 TCP 听起来很简单,但 TCP 存在于与操作系统紧密结合的最底层。简单来说,TCP 的代码存在于内核层而不是用户空间。考虑到庞大的设备数量,要在内核空间实施更改可能需要很长时间才能影响到所有用户。

因此,谷歌提出了一种新的协议 QUIC,作为 TCP 的替代品。与 TCP 一样,QUIC 也是一个传输层协议。然而,它位于用户空间而不是内核空间。这使得它比 TCP 更容易更改和增强。

QUIC 基于 UDP 工作。它通过使用 UDP 来克服 TCP 的限制。它只是在 UDP 之上增加了一个层或包装器。这个包装器添加了 TCP 的特性,如拥塞控制、数据包重传、多路复用等。它内部使用 UDP,并在其上添加了 TCP 的最佳特性。

既然我们现在了解了 QUIC 的基本知识,让我们深入了解这个协议的工作方式。

QUIC 是如何工作的?

QUIC 握手

QUIC 基于 UDP,并且无需经历三次握手过程。三次握手过程增加了额外的开销并增加了延迟。因此,QUIC 通过减少连接延迟来提高性能。

在 TCP 的情况下,用于 TLS 的额外握手也会增加延迟。QUIC 在单个调用中结合了 TLS 握手和 QUIC 握手。通过优化握手过程,它提高了性能。

可靠性

你可能会想:“既然 QUIC 基于 UDP,数据包会不会丢失呢?”答案是否定的。QUIC 在 UDP 堆栈上增加了可靠性。例如,如果服务器没有从客户端收到第 5 个数据包,协议将检测到这一点,服务器将要求客户端重新发送相同的数据包。

多路复用

与 TCP 类似,QUIC 也实现了多路复用。客户端可以同时使用单个通道传输多个文件。QUIC 为每个流(传输的文件)创建一个 UUID。它使用 UUID 来识别流。然后,多个流通过一个单一通道发送。

下图说明了 QUIC 中多路复用的工作机制:

alt

QUIC 中的多路复用

QUIC 通过其多路复用也解决了 TCP 面临的队头阻塞问题。如果一个流遭受数据包丢失,仅该流会受到影响。QUIC 中的流是独立的,不会相互影响。

安全性

此外,QUIC 还支持 TLS 1.3(传输层安全)。这保证了数据的安全性和保密性。TLS 加密了 QUIC 协议的大部分,如数据包编号和连接关闭信号。

为什么选择 QUIC?

  • 减少延迟 - 通过结合 TLS 握手和连接设置,QUIC 最小化了延迟。这也被称为 0-RTT(零延迟请求)。它结果在更快的连接建立和提高了 Web 应用的性能。
  • 多路复用 - 通过多路复用,QUIC 可以通过单一通道发送多个数据流。这对下载多个文件(如图片、JavaScript、CSS 等)的客户端应用程序非常有帮助。
  • 连接迁移 - 使用 QUIC,您可以在不中断的情况下从一个网络接口切换到另一个(例如从 WiFi 切换到移动数据)。这对移动设备来说很重要,提升了用户体验。
  • 提升安全性 - QUIC 运作于 TLS 1.3 之上,提供更好的安全性。此外,它还加密了协议的大部分内容,与仅加密 HTTP 负载的 TCP+TLS 相比,它对安全攻击具有更高的抵抗力。
  • 广泛支持 - 自从它推出以来,它的采纳率一直在增长。这进一步加强了其有效性。

HTTP/3 和 QUIC

HTTP/3 是超文本传输协议(HTTP)的最新版本。它在内部使用 QUIC 而不是 TCP。它旨在为现代 Web 提供一个更高效和安全的基础。它具有 QUIC 提供的所有好处。

HTTP/3 由 IETF 标准化。今天,大部分互联网流量都依赖于 HTTP/3。

alt

从上图可以看出,采用率飙升至 30%,并且正逐渐超过 HTTP/1.1。随着采用率的增长,HTTP/3.0 将在未来几年逐渐超过 HTTP/2.0

结论

自 HTTP 三十年前问世以来,互联网已经取得了长足的进步。HTTP的演进使在线体验变得更加高效和响应迅速。随着现代应用的不断增长需求,我们意识到了底层协议如 TCP 的固有限制。

Google 开发了变革性的协议 QUIC。它利用 UDP 并解决了 TCP 的所有缺陷。减少延迟、多路复用、增强安全性和连接迁移是 QUIC 的一些显著特征。QUIC 带来的创新解决了队头阻塞等问题。

像谷歌和 Facebook 这样的大型技术公司通过在 HTTP/3 中采用 QUIC,看到了性能的显著提升。随着采用率的上升和支持的增加,HTTP/3 将成为互联网通信的标准。在未来几年内,互联网将演变并过渡到 HTTP/3,以实现更高的效率、可靠性和性能。

全部评论
昨天被字节面到了,可恶啊😭
点赞 回复 分享
发布于 2024-08-20 09:21 湖北

相关推荐

作为一名大数据工程专业的研究生,收到华为的实习面试邀请后,我既兴奋又有点紧张。华为在大数据、云计算和AI方面的项目一直颇具规模,我在实验室也经常用到华为云的分布式存储和计算工具,所以这次机会对我来说既是挑战,也是检验自己能力的时刻。面试当天是线上视频面试,HR提前一天发来了会议链接,还贴心地提醒我准备好稳定的网络和耳麦。面试开始,首先是自我介绍环节,我简单交代了自己的学业背景、参与过的项目,以及在实验室做的两个与数据仓库建设相关的课题。技术面提问部分面试官是一位资深的大数据架构师,第一句就直奔主题:“你在项目中具体承担了哪些角色?有没有数据模型设计的经验?”我提到了在校期间参与的一个基于Kimball维度建模的销售分析系统项目,并详细描述了如何在需求分析阶段识别业务过程和度量,以及如何根据不同的数据主题域设计星型模型与雪花模型。我还补充说明了在ETL流程中,如何处理缓慢变化维(SCD),尤其是Type 2类型的实现方法,包括在Hive中通过分区与有效期字段来管理历史数据。他听完后很感兴趣,追问:“如果我们有一个订单事实表,需要支持多维度分析,比如时间、客户、产品,但不同维度的数据规模和更新频率差异很大,你会怎样设计?”我答道:时间维度:预先生成完整的日期维并缓存在DW中,保持稳定不变;客户维度:考虑缓慢变化维,保证历史分析的准确性;产品维度:用码表+关联,保持高查询性能。并说明了在分布式环境(如Spark SQL)下,为避免join带来的性能瓶颈,可以使用广播join或分桶策略。场景题与解决思路接下来,他给了一个具体问题:“如果每天有上亿条设备日志进入系统,需要在分钟级完成故障模式检测,你会怎样设计架构?”我回答:数据采集:采用Flume/Kafka作为实时数据入口,将日志按主题与分区进行路由;实时计算:使用Flink进行流处理,通过窗口函数实现分钟级聚合;特征提取与模式匹配:在流计算过程中调用预先训练好的模型(可能是基于TensorFlow或PyTorch),完成在线推理;数据落地与分析:实时结果入ClickHouse或HBase,历史数据入Hive供离线分析;监控与告警:接入Prometheus+Grafana实现实时监控,并结合规则引擎触发告警。面试官点头认可,但提醒我在实际生产中需要考虑容错和数据延迟问题,比如Kafka的副本机制、Flink的checkpoint与状态恢复等。综合能力考察除了技术问题,他还考察了我的沟通能力与学习能力。他问:“如果你负责的某个数据模块上线后用户反馈查询慢,你会怎样定位问题?”我回答说会先定位问题范围:是前端展示慢还是后端查询慢;如果是后端,先看sql执行计划,分析是否由于join、group by等操作导致大量shuffle;再检查数据倾斜情况,必要时用加盐、按范围拆分等方式优化;同时关注底层存储的索引与分桶方式。思维延展与职业规划最后,他关心我的职业规划。我表示自己未来希望在数据架构与数据治理方向深耕,不仅掌握数据采集、处理、存储的全链路技术,还能从业务视角建立完善的维度模型和指标体系,提高企业数据资产价值。这与华为在智慧城市、通信网络、云平台等领域的需求非常契合。面试在轻松的氛围中结束,面试官说技术能力还不错,但建议我在模型设计中更多考虑跨域数据整合的复杂性,以及如何在超大规模数据环境下保持模型的易维护性。HR最后告知后续会有二面,可能会有更深层的系统设计题与现场编码题。面试感受与经验总结这次一面让我体会到几个关键点:准备要针对岗位需求 —— 华为的大数据实习不只是写代码,还要理解业务流、模型设计、性能优化,尤其是Kimball建模在企业级场景的落地方式。案例要具体 —— 面试时举的例子最好能体现规模、挑战与解决方案,比如数据量级、延迟要求、架构选型等细节。思维要全面 —— 技术方案不仅要能跑通,还要考虑高可用、可扩展性、运维成本等。表达要清晰 —— 把复杂的设计讲清楚,有时候比技术本身更重要。总之,这次面试虽然是虚拟的情景,但过程很真实,如果你未来准备大数据方向的华为面试,可以借鉴这种“技术细节+业务场景+性能优化”的答题方式,即使遇到陌生问题也能从架构思路入手,让面试官看到你的系统性思考能力
点赞 评论 收藏
分享
一、 开场及背景了解自我介绍:你可以简单地自我介绍一下吗?项目性质:所以这两个项目主要是你个人的练手项目,对吧?实习经历:中间有参加过什么其他公司的实习之类的吗?或者跟着导师/师兄做一些正式的项目?求职规划:为什么没有实习经历?是因为机会比较少,还是个人规划的原因?(面试官补充:因为计算机专业通常很看重实践经验,理论上机会也比较多)所以考虑实习这件事是比较晚的吗?同辈情况:你身边的同学(的求职/升学情况)呢?二、 技术问题:计算机基础CPU缓存:CPU周围的L1, L2, L3这些多级缓存,它的主要作用或者意义是什么?因为这些缓存的存在,如何保证数据的一致性?CPU缓存(追问):既然第一次访问数据需要从主内存加载到各级缓存,这是否意味着第一次访问反而会更慢?缓存的“预读”(prefetching)机制是指什么?(面试官举例:我只想读一个变量,但它把一整块数据都读进来了,这是为了加速后续的访问吗?)并发与锁:在并发编程中,自旋锁和互斥锁分别适用于什么样的场景?并发与锁(结合项目追问):在你的实际项目中,有用到自旋锁的场景吗?可以举个例子吗?(针对你回答的动态选择策略)所以这是取决于你要更新的缓存数量,动态决策使用互斥锁还是自旋锁吗?你是这么实现的吗?你有对比过这两种策略(自旋锁 vs 互斥锁)的性能差异吗?比如,缓存数量达到多少或者耗时多长,你会切换策略?那你当时的策略具体是怎样的?比如说,更新多少个缓存的时候会采用自旋锁?三、 技术问题:C++语言菱形继承:C++的多重继承会产生菱形继承问题,你可以描述一下这具体是个什么样的问题吗?采用虚继承的方式可以彻底解决这个问题吗?会不会带来任何其他问题?菱形继承(追问):如果我们继承的两个类(A和B),我们不确定它们背后是否有一个共同的基类,那是不是意味着最好总是采用虚继承的方式,以避免潜在问题?拷贝与移动构造:你了解C++的拷贝构造函数和C++11引入的移动构造函数吗?它们俩的差异和应用场景是什么?拷贝与移动构造(结合项目追问):在你实际的项目中也有使用过(移动构造/移动语义)吗?四、 技术问题:网络协议TCP挥手:为什么TCP断开连接是四次挥手,而不是三次?TIME_WAIT状态:TCP主动关闭方在最后一次挥手后,为什么要进入一个TIME_WAIT状态并等待一段时间?TCP替代方案:TCP的TIME_WAIT机制会延长连接释放时间。现在有没有一些新的协议(比如QUIC)针对这一点做了优化,既能保证正常运行,又能有更好的连接释放性能?QUIC协议(追问):QUIC协议是如何做到在1-RTT(甚至0-RTT)就完成连接建立的?五、 技术问题:数据结构与算法LRU缓存:你了解LRU(最近最少使用)缓存淘汰算法吗?请讲讲思路,如何实现一个高性能的LRU数据结构?(针对你的回答)链表部分你会采用单向链表还是双向链表?逻辑算法题(扔弹珠/鸡蛋问题):你面前有一栋100层的楼,你手上有两个完全一样的玻璃弹珠。从某个楼层往下扔,要么碎,要么不碎,且楼层越高越容易碎。现在要找到那个“刚好会碎”的临界楼层,你觉得怎么样能够最快地找到?(面试官补充:不碎的弹珠可以重复使用,碎了就没了)六、 反问环节反问机会:我这里主要就这些问题了,你看看你有什么想要问或者想要了解的吗?
查看30道真题和解析
点赞 评论 收藏
分享
评论
1
4
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务