news 2026/5/8 15:25:52

Cloudflare 用一年时间重写了运行 15 年的核心系统,性能提升 25%

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Cloudflare 用一年时间重写了运行 15 年的核心系统,性能提升 25%

一个关于技术债的故事

每个足够长寿的软件系统,最终都会面临同一个问题:它在被设计时做出的每一个合理决策,都会随着时间的推移慢慢变成约束和包袱。

Cloudflare 把这件事做了一遍,而且做得相当彻底。

Cloudflare 的网络中有一个叫做 FL 的核心系统,可以被称为整个网络的"大脑"。每一个到达 Cloudflare 网络的请求,都会经过 FL 的处理——从执行 WAF 规则和 DDoS 防护,到将流量路由至 Developer Platform 和 R2。

这个系统已经运行了 15 年。现在,它被重写了。


15 年的演进轨迹

FL 的第一行代码由 Cloudflare 创始人之一 Lee Holloway 提交,时间是 2010 年 1 月,距离公司正式发布还有 9 个月。第一版基于 NGINX,产品逻辑用 PHP 实现。

commit 39c72e5edc1f05ae4c04929eda4e4d125f86c5ce Author: Lee Holloway Date: Wed Jan 6 09:57:55 2010 -0800 nginx-fl initial configuration

3 年后,这套系统变得过于复杂、响应过于缓慢,于是进行了一次几乎完全的重写。这次重写由现任 CTO Dane Knecht 主导,标志性的一个提交是:

commit bedf6e7... Author: Dane Knecht Date: Thu Sep 19 19:31:15 2013 -0700 remove PHP.

从此,FL 基于 NGINX、OpenResty 框架和 LuaJIT 实现。这套组合在很长一段时间里运行良好,但近年来开始显露出疲态:团队不得不花费越来越多的时间修复 LuaJIT 的各种边角 Bug;Lua 代码高度动态和非结构化的特性,在快速实现逻辑时是优势,但在集成大量复杂产品逻辑时变成了错误的温床;每引入一个新产品,都必须逐一检查它是否会影响现有的所有其他产品。

2024 年 7 月,新系统 FL2 的第一行代码提交。


为什么选择 Rust 和 Oxy?

FL2 用 Rust 语言构建,基于 Cloudflare 自研的代理框架 Oxy。

Rust 的选择并不出人意料——Cloudflare 已经在多个关键系统中使用 Rust,积累了深厚的工程经验。Oxy 框架已经在多个主要 Cloudflare 服务上经过生产验证,包括 Zero Trust Gateway 和 Apple iCloud Private Relay,团队对它能够应对 FL2 将会遇到的各种流量模式和协议组合有充分的信心。

从工程层面看,Rust 解决的最核心问题是安全性:Rust 在编译期就能消除整类 Bug,包括内存安全问题和数据竞争,同时提供 C 语言级别的运行时性能。在 Cloudflare 的规模下,这些保证不是锦上添花,而是必不可少的。

平滑重启:让更新对用户不可见

在 FL1 中,升级意味着重启代理进程,重启会立即断开所有活跃连接——对 WebSocket、流媒体会话和实时 API 等长连接尤其痛苦。

Oxy 内置了优雅重启机制:当新实例启动时,旧实例停止接受新连接,但继续服务现有连接,直到这些连接自然结束。这意味着如果你在某次 Cloudflare 部署更新时正在进行一个 WebSocket 会话,那个会话可以不受影响地继续,而不是被重启强行中断。

Cloudflare 还使用了 systemd socket activation——让 systemd 创建和持有套接字,而不是由每个代理进程自己管理。这将套接字的生命周期与 Oxy 进程的生命周期解耦:即使进程重启或崩溃,套接字依然保持开放,新进程启动后可以立即接管。


FL2 的模块系统:让产品逻辑之间的关系变得显式

FL1 最大的工程痛点不是性能,而是复杂性——随着产品数量增长,没人能一眼看清楚哪些模块会相互影响。

FL2 用一套严格的模块系统从根本上解决了这个问题:

模块系统强制执行几条严格规则:模块不能执行任何 IO;每个模块提供一组"阶段(Phase)";阶段按严格定义的顺序执行,对每个请求都一致;每个阶段明确声明其输入和输出,并在编译时强制校验。

这意味着,一个模块能接收什么数据、能产出什么结果,在代码写完之前就已经是强约束。不存在隐式的状态共享,也不存在意外的副作用。

模块之间通过"模块值(Module Value)"传递信息——一个模块可以声明自己依赖另一个模块的输出,这种依赖关系在编译时就被检查。

另一个重要设计是过滤器(Filter):每个模块可以提供一组过滤条件,控制它是否需要在某个请求上运行。这意味着不是每个请求都要跑所有产品的逻辑,而是只运行真正需要的模块集合。每新增一个产品,它的处理开销不再无差别地叠加到所有请求上。


如何替换一个正在运行的系统:四步迁移

重写一个处理全球数十亿请求的核心系统,不能停机,不能中断业务,还不能让任何一个已有功能出错。这本身就是一个极具挑战性的工程问题。

第一步:让 Rust 模块先在旧系统里跑起来

团队没有要求各产品团队同时维护 Lua 和 Rust 两套实现。而是在旧的 NGINX/OpenResty 框架里实现了一个适配层,允许新的 Rust 模块直接在其中运行。产品团队可以用 Rust 实现逻辑、替换旧的 Lua 代码,而不必等待整个系统迁移完成。

第二步:自动化测试框架 Flamingo

Cloudflare 构建了一套内部命名为 Flamingo 的系统,可以并发运行数千个完整的端到端测试请求,同时打到生产和预生产系统上。相同的测试集同时跑在 FL1 和 FL2 上,确保行为一致。

每次部署变更时,变更会经过多个阶段逐步推出,每个阶段都需要全套测试通过,且性能和资源使用指标在可接受范围内,才能自动进入下一阶段。如果测试失败,系统会自动暂停或回滚。这套机制让 FL2 中新功能的构建和发布时间压缩到了 48 小时以内,而在 FL1 中这通常需要数周。

第三步:Fallback 机制——FL2 处理不了就透传给 FL1

如果 FL2 收到一个它还不知道如何处理的请求或配置,它会执行"回退(Fallback)"——在网络层把整个请求的字节流透传给 FL1 继续处理。这让 FL2 在功能尚未完全覆盖的情况下就可以开始接收真实流量。

Fallback 还有一个额外用途:当某个功能在 FL2 中已经实现,但想验证其行为是否与 FL1 完全一致时,可以先在 FL2 中执行逻辑,然后触发 Fallback,通过对比两个系统的行为来获得高置信度。

第四步:从免费用户开始,逐步扩大流量比例

2025 年初,FL2 开始承接真实用户流量,从免费用户开始,全年持续提高流量比例。整个过程中,团队实际上在追踪两条曲线:一条是路由到 FL2 的流量占比(持续上升),另一条是 FL2 无法处理而回退至 FL1 的流量比例(持续下降)。Cloudflare 社区的 MVP 用户充当了早期预警系统,帮助快速识别潜在问题。


量化收益:数字说话

性能测试结果清晰:中位响应时间降低了 10ms,第三方 CDN 性能测试(CDNPerf)显示性能提升了 25%。

性能提升的原因很直接:

减少了无谓的计算:过滤器机制确保每个请求只运行需要的模块,而不是像 FL1 那样对所有请求跑完所有产品逻辑。

消除了跨语言转换开销:FL1 同时包含 NGINX(C)、LuaJIT(Lua + C 接口层)和 Rust 模块,系统需要花费大量时间和内存在不同语言的数据表示之间做转换。FL2 是单一代码库,用同一种语言实现,这部分开销彻底消失。

资源使用同样大幅改善:内部测量显示,FL2 的 CPU 使用量不足 FL1 的一半,内存占用同样大幅下降。这意味着释放出的计算资源可以用来交付更多产品功能。


安全性:Rust 的编译期护栏

FL2 在设计上比 FL1 更安全。Rust 语言在编译期的内存检查和类型系统,避免了大量错误。结合严格的模块系统,绝大多数改动都可以以较高的信心进行。

Cloudflare 长期以来有一个政策:系统的任何无法解释的崩溃都必须作为高优先级问题调查。FL2 中,目前为止此类崩溃的主要原因是硬件故障,而非软件 Bug——这大幅降低的软件崩溃率,让团队有充足的时间做好每一次调查。


下一步:把 NGINX 从系统中彻底清除

FL2 的迁移预计在 2025 年底完成,FL1 将在 2026 年初关闭。

还有一个服务尚未完成迁移:处于请求链路最前端的"HTTP & TLS 终止层"同样是一个 NGINX 服务,目前正在进行 Rust 重写,预计明年初完成。

当这一切完成之后,整个系统将完全模块化、完全基于 Rust,届时可以开始更深入的优化——重组模块连接方式、扩展对非 HTTP 流量(如 RPC 和流式传输)的支持,以及更多。


总结

这篇博客描述的事情,从外部看是一次性能升级公告——响应时间降低 10ms,性能提升 25%,CPU 减少一半。但如果只看这些数字,会错过更重要的东西。

更值得关注的,是 Cloudflare 在这一年里完成的一件工程层面的硬事:在不停机、不中断业务、不影响现有功能的前提下,把一个支撑全球数十亿请求的 15 年老系统,从里到外换掉了

这背后需要的不只是写出更好的代码,还需要 Fallback 机制提供安全网、Flamingo 测试框架提供信心、自动化灰度发布控制风险,以及把迁移过程拆解成能够并行推进的小步骤。

这套"替换正在运行的系统"的方法论本身,或许比 Rust 和 25% 的性能提升更值得借鉴。


参考来源:Cloudflare Blog — “Cloudflare just got faster and more secure, powered by Rust”

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/8 15:25:50

别再死记硬背了!用一张图+三个实战案例彻底搞懂AutoSAR CanNM状态机

可视化拆解AutoSAR CanNM状态机:3个真实案例全状态流程图解 在汽车电子领域,网络管理(NM)模块的设计质量直接影响着整车能耗表现和系统稳定性。作为AUTOSAR架构中的关键组件,CanNM状态机因其复杂的转换逻辑和定时器交互…

作者头像 李华
网站建设 2026/5/8 15:25:48

Zynq 7000 SDK裸机CAN调试避坑指南:PS端100MHz时钟配置与PL端时钟计算详解

Zynq 7000 PS端与PL端CAN裸机调试实战:从时钟配置到寄存器计算的完整避坑手册 调试Zynq 7000的CAN接口时,最令人头疼的往往不是协议本身,而是那些隐藏在时钟树和寄存器配置里的魔鬼细节。记得第一次在PS端实现CAN通信时,我花了整整…

作者头像 李华
网站建设 2026/5/8 15:25:34

Diablo Edit2:暗黑破坏神2存档编辑器终极指南

Diablo Edit2:暗黑破坏神2存档编辑器终极指南 【免费下载链接】diablo_edit Diablo II Character editor. 项目地址: https://gitcode.com/gh_mirrors/di/diablo_edit 你是否厌倦了在暗黑破坏神2中花费数百小时重复刷装备?是否因为一次错误的技能…

作者头像 李华
网站建设 2026/5/8 15:25:19

如何构建企业级AI客户端?Chatbox技术架构深度解析

如何构建企业级AI客户端?Chatbox技术架构深度解析 【免费下载链接】chatbox Powerful AI Client 项目地址: https://gitcode.com/GitHub_Trending/ch/chatbox 在AI应用日益普及的今天,如何构建一个功能全面、性能稳定且支持多模型的企业级AI客户端…

作者头像 李华
网站建设 2026/5/8 15:25:07

AI智能体核心技术解析:从推理、记忆到工具使用的2026全景图

1. 项目概述:一份面向未来的AI智能体全景图如果你最近也在关注AI领域,特别是智能体(AI Agent)这个方向,可能会和我有同样的感受:信息爆炸,但良莠不齐。每天都有新的论文、新的框架、新的开源项目…

作者头像 李华
网站建设 2026/5/8 15:23:24

开关电源——BUCK和BOOST的基础工作原理(学习随笔)

BUCK基础工作原理最原始的降压开关电源工作原理 假设负载为图中右侧的100Ω电阻,假如降到5V,首先闭合开关,电容开始充电,当检测到电容两端电压达到5V时断开开关,此时电容开始放电,电压下降,再次…

作者头像 李华