【技术贴转载】HTTP协议演变:为什么QUIC是顺应大势?

了解点技术姿势,以后和甲方爸爸忽悠,不对,谈判的时候可以装的更高大上点~

1.HTTP/1.0 面临的问题

HTTP/1.0 中每个请求、响应对都先打开一个 TCP 连接,数据传输结束后关闭该连接。 这导致了很大程度的延迟,人们想出一种称为 keep-alive 的变通方法,它在 HTTP 请求之间重用 TCP 连接,然而本质上是延迟关闭连接, 下面是是否开启 keep-alive 的对比图。

【技术贴转载】HTTP协议演变:为什么QUIC是顺应大势?

带和不带keep-alive的 HTTP 1.0

此示例还演示了在发出 HTTP 请求之前需要建立的 TCP 3 方式握手。 本质上,双方都使用序列号(SYN 数据包)跟踪发送的内容。 因此,如果丢失任何数据包,可以从最后一个序列号重新传输。 请注意 3 次握手(SYN、SYN-ACK、ACK)需要作为每个连接建立的一部分来完成。 由于 TCP 是双向通信模式,每个方向都需要 ACK,而 FIN 用于关闭 TCP 连接。

Keep-alive 看起来很好,然而仔细观察,每个资源请求仍然需要在触发之前完成其依赖资源的请求。例如,在 index.html 返回之前,无法触发对 index.css 的请求。

2.HTTP/1.1 和 HTTP/2

2.1 HTTP/1.1 的管道(pipelining)机制

在 HTTP/1.1 中引入了一种称为管道(pipelining)的特性。使用此功能,可以立即发出通过 TCP 连接的每个 HTTP 请求,而无需等待前一个请求的响应返回,如下图:

【技术贴转载】HTTP协议演变:为什么QUIC是顺应大势?

HTTP/1.1的管道特性

响应将以相同的顺序返回,这引入了一个称为 HTTP Head of Line (HOL) Blocking 的问题。假设您正在请求一张猫图片(无法获得足够多的猫的图片)和一个 javascript 文件。如果图像尺寸很大,服务器在完成图像发送之前不会开始发送 javascript 文件。

最初的方法是让浏览器打开最多 6 个到同一服务器的连接,并且作为优化性能,开发人员开始跨多个域共享资源以支持服务器上超过 6 个资源的情况。 然而,这并没有解决为每个单独的连接设置 TCP 握手的开销。

这也引入了 css-sprites 等前端创新,以此来减少通过网络传输的单个资源的数量。很快人们意识到这无法扩展,于是引入了一种新方法,即具有多路复用功能的 HTTP/2。

2.2 HTTP/2 的多路复用机制

从本质上讲,HTTP/2 指出通过 TCP 连接的每个 HTTP 请求都可以立即发出,而无需等待先前的响应返回, 响应可能以任何顺序返回。 下图再次说明了 HTTP/1.1 管道和 HTTP/2 多路复用的情况, 请注意在使用多路复用流的 HTTP/2 中如何在 cat.png 之前返回 view.css。

【技术贴转载】HTTP协议演变:为什么QUIC是顺应大势?

左图:HTTP 1.1 的请求管道 右图:带多路复用的 HTTP 2

与 HTTP/1.1 不同的是,在 HTTP/1.1 中,资源标识仅作为一组 TCP 数据包的第一个 TCP 数据包中的 HTTP 标头的一部分,在 HTTP/2 中,每个 TCP 数据包都包含资源的标识。 这使得拆分成多个 TCP 数据包的 HTTP 响应很容易重新组合,从而消除了 HTTP/1.1 的串行性质

看起来已经最大限度地改进了 HTTP/2 多路复用,然而不完全是。这里还有一个缺陷,但需要先深入地了解 TCP 堆栈。TCP 是一种面向连接的协议,它跟踪在客户端和服务器之间传输的所有数据包,如果数据包在从服务器传输的过程中丢失,它将存储所有数据包后的数据包序列号,并且不会将它们传递给应用层,直到丢失的数据包被删除重传。 如下图:

【技术贴转载】HTTP协议演变:为什么QUIC是顺应大势?

在上图,如果来自 view.css 的数据包 2 丢失,它会导致来自 3-20 的所有数据包都存储在接收缓冲区中,并且在重新传输数据包 2 之前不会向上传递到应用层。 即使来自 cat.png 的所有数据包都已收到,但底层 TCP 协议无法知道这些信息,因此它会强制重新传输。

请注意,上图并不是一个非常准确的表示,因为已经从 HTTP 响应切换到 TCP 响应来说明问题。

【技术贴转载】HTTP协议演变:为什么QUIC是顺应大势?

如果您仔细观察,其实是因为 TCP 的潜在连接导向性所致。 例如,如果 TCP 知道数据包 1 和数据包 2 是 view.css 的一部分,它将导致仅重传数据包 2 而不会阻止数据包 3-20。这样,标记 HTTP/2 的多路复用流 ID 将会和 TCP 的包 ID 解耦。

我们知道有一种称为 UDP 的替代方法,它连接较少,但也仍然需要连接,不是吗?如何在没有连接的情况下以可靠的方式(重传、确认、排序等整个过程)请求资源?此时,我们需要一种方法来识别跨多个 TCP 数据包的资源

3.QUIC 的横空出世

3.1 TCP 该退出历史舞台了?

当上世纪 70 年代 TCP 被发明的时候,没有人会预料到 50 年之后仍然在使用它,但事实却真是如此。

在过去几十年中,TCP 不断发展,并新增了与可靠数据传输、流量控制、拥塞控制等相关的各种特性。但许多研究者、从业者都认为 TCP 已至末路。自从 TCP 发明以来,互联网已经成为社会生活中非常重要的组成部分,但遗憾的是,TCP 并没有与时俱进以满足不断增长的需求。

3.2 TCP 面临前所未有的挑战?

在 QUIC 出现以前,TCP 的主要替代选择是 UDP。TCP 提供了可靠的互联网传输,而 UDP 提供了更快、但却非可靠的传输。QUIC 的出现使得结合 TCP 最佳特性和 UDP 传输层的能力成为可能。在深入 QUIC 之前,先一起了解下 TCP 的主要限制:

  • TCP 仅定义了 40 字节的可选位,且几乎全部填满,无法扩充新特性
  • 许多中间件(如防火墙)假设 TCP 数据包将以某种确定方式构造,如果数据包与预期相差太大,就会被拒绝或者延迟,这使得 TCP 协议几乎无法发展
  • 由于 TCP 在内核实现,那么任何 TCP 传输的更新都需要经过新的内核升级,对于一些基础设施相对陈旧的公司来说,需要耗费数年才能采用新特性
  • TCP 是传输层,没有内置加密 TLS,所以需要在上层增加。导致的结果就是需要很长时间才能建立安全连接,并且一些通过 TCP 传输的数据(比如数据包头部)没有被加密,从而产生安全漏洞。

QUIC 和 HTTP/3 一起使用的目的就是代替 HTTP/1(或 2)和 TCP 的组合,以及解决 TCP 协议所带来的一些已知问题。

3.3 QUIC 如何应对 TCP 带来的挑战?

首先,在 UDP 之上构建 QUIC 的决定所带来的优势相当明显。UDP 在互联网上被广泛部署,所以无需从零开始定义传输层(否则时间成本会很高)。

相较于 TCP,UDP 的开销要少很多,这个特点使它更快速、更简单也更高效。但它存在一个重大缺陷,那就是缺乏可靠性。UDP 无法确保每个通过它发送的数据包都能正确送达,也无法确保数据包以准确顺序发送给接收方。

QUIC 继承了 TCP 的特性,将它们构建于 UDP 之上,并添加了更多其他特性。TCP 是传输层,TLS 和 HTTP2 位于其上方的应用层,QUIC 同时包含了应用层和传输层机制。因此,它的目的就是代替 TCP 传输层。

QUIC 使用 UDP 作为底层传输协议,同时内置 TLS 加密,并结合了 TCP 的可靠性特性。QUIC 在应用层(即用户空间)获得进一步实现。因此,无需更新内核即可进行大量修改。

【技术贴转载】HTTP协议演变:为什么QUIC是顺应大势?

QUIC构建于UDP之上

3.4 QUIC 的目标?

1.作为 TCP 的替代品,QUIC 在底层 UDP 数据包之上维护流,与 HTTP/2 相比,将流视为微型 TCP 连接,但处于资源级别。 换句话说,与 HTTP 相比,QUIC 保留了单个资源流中的顺序,但不再跨单个流。 这也意味着 QUIC 不再按照请求的顺序将资源传递给应用层。

2.QUIC 可以提高网络切换事件期间的性能,例如当移动设备的用户从本地 wifi 热点切换到移动网络时发生的情况。 当这种情况发生在 TCP 上时,一个漫长的过程开始,每个现有的连接一个接一个地超时,然后根据需要重新建立。 为了解决这个问题,QUIC 包含一个连接标识符,它可以唯一标记与服务器的连接,而不管来源如何。 这允许通过发送包含此 ID 的数据包简单地重新建立连接,因为即使用户的 IP 地址发生变化,原始连接 ID 仍然有效。

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

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

3.5 QUIC 为何要基于 UDP 而非 IP?

那么 QUIC 为什么需要基于 UDP,而不是 IP ?这是因为企业和互联网上的大多数防火墙仍然支持 UDP 作为协议。如果要在 IP 上分层封装 QUIC,将不得不面临大量的重新配置工作。而且,换句话来说, UDP 8 个字节的标头已经非常小了。至于安全性,QUIC 默认就支持了 TLS 了。

参考资料

https://systemweakness.com/the-evolution-of-internet-protocols-and-messaging-architectures-part-1-a228dfb8d9b8

https://www.livevideostack.cn/news/quic-and-the-future-of-internet-transmission/

https://medium.com/@the.real.yushuf/benchmarking-quic-1fd043e944c7

https://m.thepaper.cn/baijiahao_20559469

声明:本站文章,有些原创,有些转载,如发现侵权侵请联系删除。本站所有原创帖均可复制、搬运,开网站就是为了大家一起乐乐,不在乎版权。对了,本站小水管,垃圾服务器,请不要采集,吐槽君纯属用爱发电,经不起折腾。

给TA打赏
共{{data.count}}人
人已打赏
技术宅

解决 ipv6 优先访问ChatGPT造成的“not available in your country”问题

2022-12-16 8:58:29

技术宅

【技术转载】服务器是否被入侵的排查方案

2022-12-17 14:29:35

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索