云flare的tokio-quiche如何使QUIC和HTTP/3在Rust后端中成为一等公民
Cloudflare开源了tokio-quiche,这是一个异步QUIC和HTTP/3 Rust库,它使用Tokio运行时封装了经过实战检验的quiche实现。这个库在生产系统(如Apple iCloud Private Relay、基于Oxy的代理和WARP的MASQUE客户端)中得到了优化,在这些系统中,每秒它可以处理数百万个HTTP/3请求,具有低延迟和高吞吐量。tokio-quiche旨在为那些想要QUIC和HTTP/3但没有编写自己UDP和事件循环集成代码的Rust团队提供支持。
从quiche到tokio-quiche
quiche是Cloudflare使用Rust编写的开源QUIC和HTTP/3实现,被设计成低级别的无I/O库。它实现了QUIC传输状态机,包括连接建立、流量控制和流多路复用,同时不对应用程序如何执行I/O做出任何假设。要直接使用quiche,集成者必须打开UDP套接字、发送和接收数据报、管理计时器并将所有数据包数据按正确顺序喂给quiche。这种设计提供了灵活性,但它使集成容易出错且耗时长。
tokio-quiche将这种集成工作包装成一个可重用的crate。它将quiche中的无I/O QUIC或HTTP/3实现与Tokio异步运行时相结合,并公开了一个已经管理UDP套接字、数据包路由和对quiche状态机的调用的API。
基于Tokio的actor架构
在内部,tokio-quiche在Tokio之上使用actor模型。actor是具有局部状态的小任务,通过在通道上进行消息传递进行通信,这很好地与拥有内部状态并像缓冲区一样操作消息的无I/O协议实现相吻合。
主要actor是I/O循环actor,它在quiche和UDP套接字之间移动数据包。其中一个关键的消息类型是Incoming结构体,它描述了接收到的UDP数据包。异步集成遵循一个固定模式,I/O循环等待新消息,将它们转换为quiche的输入,推进QUIC状态机,然后将输出转换为写回套接字的外发数据包。
对于每个UDP套接字,tokio-quiche强生了两个重要的任务。InboundPacketRouter拥有套接字的接收部分,根据目的连接ID路由入站数据报。IoWorker是每个连接的I/O循环,驱动单个quicheConnection,交错调用quiche和应用通过ApplicationOverQuic实现的特定于应用程序的逻辑。这种设计封装了每个actor中的连接状态,使QUIC处理与高级协议代码保持隔离。
ApplicationOverQuic和H3Driver
QUIC是一个传输协议,可以携带多个应用程序协议。HTTP/3、基于QUIC的DNS和基于QUIC的媒体是IEEF标准所覆盖的例子。为了避免将tokio-quiche耦合到单个协议,Cloudflare团队公开了一个ApplicationOverQuic特例。此特例抽象了quiche方法和底层I/O,并向实现协议的应用程序提供了更高层次的事件和钩子。例如,HTTP/3调试和测试客户端h3i使用了非HTTP/3的ApplicationOverQuic实现。
在这个特例之上,tokio-quiche提供了一个专注于HTTP/3的实现,名为H3Driver。H3Driver将quiche的HTTP/3模块连接到I/O循环actor,并将原始HTTP/3事件转换为应用代码方便的高层次事件,其中有异步流体。H3Driver是通用的,并公开了ServerH3Driver和ClientH3Driver变体,它们在核心驱动程序之上添加了服务器和客户端行为。这些组件提供了与Cloudflare内部基础设施共享实现模式的HTTP/3服务器和客户端的基础。
生产使用和路线图
tokio-quiche在公开发布之前已在Cloudflare内部使用了几年。它为苹果iCloud Private Relay中的Proxy B、基于Oxy的HTTP/3服务器和WARP MASQUE客户端,以及h3i的异步版本提供动力。在WARP客户端中,基于tokio-quiche的MASQUE隧道取代了早期的基于QUIC的隧道。这些系统在Cloudflare边缘规模上运行,证明了该集成可以在生产中持续每秒数百万个HTTP/3请求。
Cloudflare将tokio-quiche定位为基础上而不是完整的HTTP/3框架。该库公开了低级别协议功能、示例客户端和服务器事件循环,并为在顶部实现意见化的HTTP服务器、基于QUIC的DNS客户端、基于MASQUE的VPN和其他QUIC应用程序的更高级别项目留下了空间。通过发布这个crate,Cloudflare旨在降低Rust团队采用QUIC、HTTP/3和MASQUE的障碍,并使外部集成与在其边缘服务中使用的传输栈保持一致。
主要要点
- tokio-quiche = quiche + Tokio:tokio-quiche是一个异步的Rust库,它将Cloudflare的无I/O QUIC和HTTP/3实现quiche与Tokio运行时集成,因此开发人员不需要手动编写UDP和事件循环管道代码。
- 基于actor的QUIC连接架构:该库在Tokio上使用actor模型,有一个根据连接ID路由UDP数据报的
InboundPacketRouter和驱动单个quicheConnection的每个任务的IoWorker,使传输状态保持隔离和可组合。 - ApplicationOverQuic抽象:通过
ApplicationOverQuic特例分离协议逻辑,它抽象了quiche和I/O细节,因此可以在同一传输核心之上实现不同的QUIC基于协议,如HTTP/3、基于QUIC的DNS或自定义协议。 - 通过H3Driver、ServerH3Driver和ClientH3Driver使用HTTP/3:tokio-quiche提供了
H3Driver以及ServerH3Driver和ClientH3Driver变体,它们将quiche的HTTP/3模块连接到异步Rust代码,并以适合典型基于Tokio的服务的方式公开HTTP/3流和体。