>_ DevTrendszh

语言

首页

语言

板块

前端 后端 移动端 DevOps AI / ML 游戏开发 安全
Rust

深入了解 Quiche:Cloudflare 的底层 QUIC 和 HTTP/3 魔法

11,606 星标

quiche

大家好!今天我想深入了解一下这个支撑当今快速互联网的代码仓库。你是否遇到过这种情况:在信号不稳定的 Wi-Fi 环境下用手机打开网站,加载得异常缓慢?或者一张"重量级"图片阻塞了整个页面的加载?TCP 协议作为网络技术的老将,在移动时代确实有其局限性。而这正是 QUIC 登场的时候。

而让你能够"烹饪"这个 QUIC 的工具就是 quiche——来自 Cloudflare 的项目。让我们来弄清楚这个"派"到底是什么,以及为什么它可能对每个系统开发者都很有趣。

什么是 Quiche,为什么你需要它?

简而言之,quiche 是一个实现 QUIC 传输协议和 HTTP/3 应用协议的 Rust 库。它由 Cloudflare 创建并被积极使用,用于处理其所有的 HTTP/3 流量。

"好吧,又一个 HTTP 库,"你可能会想。但这里有一个重要的细微差别。Quiche 是一个底层实现。这在实践中意味着什么?它不会给你一个现成的 HTTP 客户端或服务器。相反,它为你提供了一个强大的 API 来管理 QUIC 连接状态和处理数据包。所有与套接字、异步操作和定时器相关的工作都留给你自己。

这就好比你得到的不是一辆现成的汽车,而是一台强劲的、组装精良的发动机。你自己决定要装什么车身、装什么轮子,以及传动系统是什么样的。这提供了令人难以置信的灵活性和控制力,这对于高性能系统至关重要。

顺便说一句,用户对项目的认真态度可以从它的使用者看出来:

  • Cloudflare:他们的整个边缘网络使用 quiche 来支持 HTTP/3。
  • Android:从 Android 11 开始,DNS 解析器使用 quiche 来实现 DNS-over-HTTP/3,提高了隐私保护和域名解析速度。
  • curl:没错,老牌工具 curl 能够使用 HTTP/3 正是得益于与 quiche 的集成。

关键特性:深入了解内部原理

让我们探索一下是什么让 quiche 对严肃项目如此有吸引力。

1. 完全掌控 I/O

正如我提到的,quiche 不会夺走你对网络的控制权。你的代码负责读取和发送 UDP 数据包。工作流程大致如下:

  1. 你从套接字接收一个 UDP 数据包。
  2. 通过 conn.recv() 方法将其传递给 quiche 连接。
  3. 库处理数据包,改变内部连接状态(例如,确认数据接收、处理流量控制命令)。
  4. 你定期调用 conn.send() 方法从 quiche 获取准备发送的 UDP 数据包,然后自己通过套接字发送。

这允许你将 quiche 集成到任何、甚至最奇特的网络引擎或事件循环中,无论是 miotokioasync-std 还是自定义构建的。

2. Rust 的安全性和速度

网络协议是一个内存管理错误可能导致严重漏洞的领域。用 Rust 编写这样的库是一个战略性的选择。Rust 在编译器级别提供内存安全保证,这消除了整类 bug(如缓冲区溢出或数据竞争),同时又不牺牲 C/C++ 的性能特性。

3. 灵活的流处理

QUIC 是一个多路复用协议。这意味着在一个单一连接内,可以有许多独立的流。一个流中的丢包不会阻塞其他流(再见了,"队头阻塞"!)。

Quiche 为处理这些流提供了一个简单清晰的 API:

// Отправляем данные в поток с ID=0
if conn.is_established() {
    conn.stream_send(0, b"hello", true)?;
}

// Проверяем, в каких потоках есть данные для чтения
if conn.is_established() {
    for stream_id in conn.readable() {
        while let Ok((read, fin)) = conn.stream_recv(stream_id, &mut buf) {
            println!("Получено {} байт в потоке {}", read, stream_id);
        }
    }
}

这种方法使得实现 HTTP/2 和 HTTP/3 特有的复杂交互场景变得容易。

4. 其他语言的 API(C/C++)

有趣的是,开发者们没有将自己限制在 Rust 生态系统中。Quiche 有一个 FFI 层(外部函数接口),提供了 C API。这意味着你可以将 quiche 编译为静态库(libquiche.a),并在你的 C、C++、Python、Go 以及任何可以调用 C 函数的项目中使用 QUIC 的全部功能。

这为将 HTTP/3 集成到现有应用程序中开辟了巨大的可能性,无需完全重写它们为 Rust。

在实践中它是如何工作的?

让我们看看 quiche 中的连接生命周期。它完美地体现了这个库的哲学。

  1. 配置。首先,创建一个 Config 对象,在其中配置 QUIC 版本、协议、流和数据限制,以及 TLS 参数。
  2. 创建连接。客户端使用 quiche::connect(),服务器使用 quiche::accept()。在这个阶段,你提供连接 ID 和网络地址。
  3. 主循环。这里是应用程序的核心:
    • 接收数据包:你从套接字读取数据,并通过 conn.recv() 将其"喂"给连接。
    • 发送数据包:你在循环中调用 conn.send(),直到它返回 Done 错误。你将收到的数据包发送到套接字。
    • 定时器管理:QUIC 是一个有状态的协议,它关心定时器(例如,用于重传数据包)。你必须定期调用 conn.timeout() 来找出下次需要"唤醒"连接的时间。当定时器触发时,你调用 conn.on_timeout(),之后再次尝试通过 conn.send() 发送数据包。

是的,这比简单地调用 http.get("...") 更复杂。但这种复杂性正是给你对网络性能和行为的完全控制的原因。

谁应该尝试 Quiche?

Quiche 不是你写简单 Telegram 机器人时需要的工具。它是为更严肃的任务而构建的:

  • 网络基础设施开发者:代理服务器、负载均衡器、CDN。
  • Web 服务器和框架创建者:用于原生 HTTP/3 支持。
  • 游戏和实时应用开发者:在那里低延迟和丢包恢复能力很重要。
  • 构建自定义协议的人:QUIC 是在 UDP 之上构建自己可靠协议的绝佳基础。

来自 Cloudflare 的Quiche是一个很好的例子,展示了像 Rust 这样的现代工具如何实现安全且性能卓越的互联网基础协议实现。这不是一个面向初学者的库,但对于有经验的系统工程师来说,它是处理 QUIC 和 HTTP/3 的真正瑞士军刀。

如果你想窥探网络的未来,从底层了解网络是如何工作的,或者你需要为你的高负载项目提供一个可靠、经过实战检验的工具——一定要去看看 cloudflare/quiche 代码仓库。尝试运行客户端和服务器示例——这是让你自己"动手"了解协议的好方法。

相关项目