原文作者:NGINX
原文链接:概念回顾:QUIC 和 HTTP/3
转载来源:NGINX 开源社区
NGINX 唯一中文官方社区 ,尽在 nginx.org.cn
编者按——11 月 2 日(周四)下午 3 – 4 点,我们在线上直播活动中将介绍并讨论 QUIC 的基本概念和发展历程,并将通过一个动手演示实验为您展示如何安装并配置 NGINX,通过 QUIC+HTTP/3 以及 TCP+TLS+HTTP/1+2 来交付网络流量。
如果您对本次活动感兴趣,请关注公众号《NGINX开源社区》,我们将于下周发布报名及观看方式。期待在本次直播活动中与您交流探讨!
快速 UDP 网络连接(QUIC)是一种通用传输层协议,旨在通过其灵活性、内置的安全防护、较少的性能问题以及更快的采用率来取代传输控制协议(TCP)。
QUIC 最初由谷歌开发,采用用户数据协议(UDP)作为在客户端和服务器之间移动数据包的低级别传输机制。另外值得注意的是,QUIC 集成了传输层安全防护(TLS),将其作为一个集成组件,而不是像 HTTP/1.1 和 HTTP/2 那样将其作为一个附加层。
基于 QUIC 的 HTTP/3 是超文本传输协议(HTTP)的第三个主要版本,于 2022 年被采纳为 IETF 标准。创建 QUIC+HTTP/3 是为了解决 TCP 固有的性能限制和用户体验的问题。
HTTP 传输协议栈概览
QUIC+HTTP/3 基础知识
QUIC 的目标是为 HTTP/3 提供高性能、高可靠性和高安全性的传输协议(尽管 QUIC 也适用于非 HTTP 流量)。
UDP、TCP 和 TLS
UDP 是一种简单、轻量级的协议,不需要像 TCP 那样复杂的三方握手来建立第一个连接。这种简单性使 UDP 性能极快且无连接,但也意味着与 TCP 相比,它缺乏可靠且安全通信所必需的功能。
QUIC 是独一无二的,因为它融合了 UDP 和 TCP 协议的优点。
虽然它是无连接的(connectionless),并利用了 UDP 作为底层传输协议来减少连接和传输延迟,但由于它重新实现了 TCP 的连接建立和丢失检测功能,从而保证了数据包的传输,因此它在更高的传输层是面向连接的。它可以处理识别丢失数据并完成重新传输的任务,以确保无缝的用户体验。
QUIC 还将 TLS 作为一个集成组件,而不是像 HTTP/1.1 和 HTTP/2 那样作为一个附加层。这种集成确保了在默认情况下实现消息加密。
QUIC 网络概述
下图描述了 QUIC 网络的基本结构。如图所示,包含 HTTP/3 请求、响应以及所有应用数据的逻辑对象是 QUIC 流。在不同的网络端点之间进行传输时,QUIC 流被封装在多个逻辑层中。
QUIC 数据流图解
从外向内看,这些逻辑层和对象包括:
-
UDP 数据报 – 包含一个指定了源端口和目标端口(以及长度与校验数据)的请求头,后跟一个或多个 QUIC 数据包。数据报是通过网络从客户端向服务器传输的信息的单位。
-
QUIC 数据包 – 包含一个 QUIC 请求头和一个或多个 QUIC 数据帧。
-
QUIC 请求头 – 包含关于数据包的元数据。QUIC 请求头有两种:
-
长请求头:在建立连接时使用。
-
短请求头:在连接建立后使用。它包含连接 ID(connection ID)、数据包编号(Package Number)和 key phase(用于跟踪哪些密钥被用于加密数据包,以支持密钥轮换),以及其他数据。对于一个特定的连接和 key phase 来说,其数据包编号是独一无二(并且不断增加)的。
-
数据帧 – 包含类型(type)、数据流 ID(stream ID)、偏移量(offset)和流式数据。流式数据分散在多个数据帧中,但可以使用连接 ID(connection ID)、数据流 ID(stream ID)和偏移量(offset)进行组合,从而以正确的顺序呈现数据块。
-
数据流 – 单个 QUIC 连接内的单向或双向数据流。每个 QUIC 连接均可支持多个独立的数据流,每个数据流都有自己的数据流 ID(stream ID)。如果某个包含一些数据流的 QUIC 数据包丢失,不在所丢数据包之中的数据流的进度不受影响(这是避免 HTTP/2 队头阻塞问题的关键。)数据流可以是双向的并可以由任意端点创建。
QUIC 与 TLS 握手的工作原理如下
TLS 握手提供了客户端和服务器之间的安全连接。QUIC 所提供的加密功能需要使用 TLS v1.3 版本。如下图所示,QUIC 保留了 TLS“内容层(Content Layer)”,它可提供加密密钥;同时,QUIC 用自己的传输机制取代了“记录层(Record Layer)”。
针对那些对安全和性能至关重要的参数,QUIC 还基于 TLS对其进行身份验证和协商。这两种协议不是严格地分层的,而是互相合作的:QUIC 借助 TLS 握手来建立安全连接,而 TLS 则使用 QUIC 提供的可靠性、有序交付以及记录层。
从较高的层面来说,TLS 和 QUIC 组件之间主要有两种类型的交互:
-
TLS 组件通过 QUIC 组件发送和接收消息,QUIC 为 TLS 提供可靠的抽象流。
-
TLS 组件为 QUIC 组件提供了一系列更新,包括(a)要安装的新数据包保护密钥和(b)状态更改,如握手完成、服务器证书等。
QUIC TLS 的 HTTP/3 支持选项
QUIC TLS 是专为 QUIC 协议设计的 TLS 变体。目前,对于在 QUIC TLS 中寻求 HTTP/3 支持的用户,有两个选项:
-
OpenSSL 的 QUIC 实现 — OpenSSL 目前正在自行实现一个完整的 QUIC 堆栈。这个实现的开发将封装所有 QUIC 功能,使 HTTP/3 用户可以更容易使用 OpenSSL TLS API,而无需担心与 QUIC 特定相关的功能。
-
支持 BoringSL QUIC API 的各种库 — 各种 SSL 库,如 BoringSL、quicTLS 和 LibreSSL(最初是 OpenSSL 的分支),现在已经可以通过实现 BoringSL 的 QUIC API 来提供 QUIC TLS 功能。这是目前想要使用 HTTP/3 的用户的唯一选择,因为 OpenSSL QUIC TLS 实现还未完善。
QUIC+HTTP/3 的优点
通过减少延迟以及改进不可靠的网络上的数据传输,QUIC+HTTP/3 旨在提高 web 应用的性能。它们的优势包括:
-
降低延迟 – 由于连接建立的过程,TCP 等传统协议存在延迟。QUIC+HTTP/3 的多路复用功能使它们能够更有效率地建立连接,从而降低建立连接和传输数据的延迟。
-
更快地连接建立 – QUIC+HTTP/3 将 TLS 握手和加密的建立过程整合到一个步骤中,减少了建立安全连接所需的通信往返次数。
-
多路复用 – 通过在单个连接中处理多个数据流,QUIC+HTTP/3 可以更有效地使用网络资源,并有助于避免队头阻塞问题。然而在传统 TCP 连接中,一个慢速数据流可能会导致其他数据流的延迟。
-
纠错功能改进 – QUIC 结合了前向纠错技术,可以帮助恢复丢失的数据包而无需重新传输,降低了数据包丢失对性能的影响。
-
降低数据包丢失的影响 – UDP 是无连接的,无需像 TCP 那样进行严格的错误检查,借此 UDP 可实现更快的数据传输。这在网络条件不太稳定的情况下尤其有利。
-
自适应的拥塞控制 – QUIC+HTTP/3 的设计比 TCP 的拥塞控制更高效、响应更灵敏,从而可以在各种不同的网络环境中获得更好的性能。
-
迁移支持 – QUIC+HTTP/3 可以在不同的网络连接之间无缝转换(例如,从 Wi-Fi 切换到蜂窝),且不会造成应用性能的波动。
-
增强安全防护 – QUIC+HTTP/3 默认集成了加密功能,增强了数据传输的安全性和隐私性。这种加密可以防止传输中的数据被窃听和篡改。
-
NAT 穿透 – QUIC+HTTP/3 对 UDP 的使用有助于网络地址转换(NAT)穿透,使其在传统 TCP 连接可能面临问题的情况下能够更直接地建立连接。
-
持续迭代 – 由于 QUIC+HTTP/3 的设计是其可通过软件来实现和更新,而不需要更改底层网络基础架构,因此它们可以被更快地更新和改进,以适应不断变化的网络条件和安全防护需求。
NGINX 唯一中文官方社区 ,尽在 nginx.org.cn
更多 NGINX 相关的技术干货、互动问答、系列课程、活动资源: 开源社区官网 | 微信公众