Cloudflare 2025-11-18 全球崩溃问题

Cloudflare 2025-11-18 全球崩溃问题

更新时间
Last updated November 19, 2025
AI 占比
Tags
经验
description
参考文档 :The Cloudflare BlogThe Cloudflare BlogCloudflare outage on November 18, 2025

一、整个故障流程概要

  1. 在 11:20 UTC 左右,Cloudflare 网络开始出现大量 HTTP 5xx 错误,用户访问很多 客户 站点都报 “内部服务器错误” 或类似提示。
  1. 最初判断为可能是 DDoS 或异常流量攻击,但其实根本原因来自内部配置/数据生成流程出错。
  1. 错误触发链大致如下:
      • 在其一个数据库系统(使用 ClickHouse)改了权限逻辑。
      • 这导致一个“特征配置文件(feature file)”被生成时,行数(features)变多、包含重复项、文件变大。
      • 这个配置文件被推送至他们全球的代理/路由节点(proxy)里。因为文件大幅超出预期,路由模块中该 Bot 管理模块(Bot Management)无法正常运行。
  1. 故障影响到了其核心代理系统(即请求流程里的关键模块),导致不仅单个服务受损,而是许多依赖 Cloudflare 代理的客户流量整体受影响。
  1. 在 14:30 UTC 左右开始恢复主流程,17:06 UTC 宣布完全恢复。

二、关键技术点拆解(前端开发者视角)

1. 特征配置文件(feature file)

  • 是什么:在其 Bot 管理系统里,有一个配置文件,其中列出了“机器学习模型要用的特征”——这些特征可能是请求的一些属性,例如请求 header/URL 模式/IP 行为等,用于判定 “这是机器人请求还是人类请求”。
  • 出错了怎样:因为数据库权限/元数据查询变更后,生成此文件的查询从原本只看一个数据库(default)的列/表变为也看底层分片数据库(r0)的列。结果:配置文件里的特征行数超过双倍(因为重复了很多底层表的列)——而该系统原本假定特征数在 ~60 内,且预分配能力支持最多 200 个。
  • 类比(前端角度)
    • 假设你做了一个前端表格组件,后台生成了一份 “字段配置” JSON,前端据此动态生成表头和表格列。你原本预设最多 20 列。但某次后台改了逻辑,让 JSON 里字段突然变成了 50 列、而且有很多重复行。结果前端组件直接崩溃(或渲染特别慢、浏览器卡死)。类似地,Cloudflare 的代理模块发现特征数超出“预分配内存限制”,就直接“panic”(程序崩溃)了。报告里有:
      thread fl2_worker_thread panicked: called Result::unwrap() on an Err value
      也就是说程序没有优雅地处理这个“特征过多”错误,而是直接 panic。

2. 代理流程 &模块(proxy / core proxy / FL2)

  • 是什么:Cloudflare 的请求流程,从 浏览器/客户端 → Cloudflare 的 HTTP/TLS 层 → “核心代理”(称为 Frontline/FL)→各种模块(如 Bot Management、WAF、缓存查找 Pingora 等)→最终到达 源服务器或缓存结果。
  • 出错了怎样:当 Bot Management 模块因为加载了过大特征文件而崩溃时,核心代理内某些请求无法正常完成这一步,就返回 5xx 错误。因为这是请求流程中的关键模块,导致整个流量(依赖该代理的客户)受到影响。报告指出,旧代理版本(FL)并未返回 5xx 错误,但 Bot 评分为 0(即判定所有流量皆为机器人);而新版本 FL2 则直接失败返回错误。
  • 类比:想象你一个 React 应用有个中间件模块 “input validator” 负责检查输入数据结构。如果这个模块丢了它的配置(或者配置出错)你可以选择两种策略:
    • 忽略这个模块(然後所有输入默认合法)→类似 FL(虽然有问题但不会报错,只逻辑违背预期)
    • 模块崩溃并阻止整个流程 →类似 FL2(用户就报错,页面挂了)。
      • Cloudflare 的代理就类似被中间模块崩毁,导致“渲染”——即响应流量——失败。

3. 内存预分配 &特征数限制

  • 是什么:为了性能,代理模块在启动或初始化时,会预先为“特征”分配内存,比如预设最多 200 特征。超过这个数就可能触发错误。
  • 出错了怎样:生成后的特征文件中行数 >200,就超出预分配范围,模块在检查此限制时触发 panic。报告中有代码片段指出这一点。
  • 类比:比如你写一个组件,假定最多 10 项列表,以优化内存或渲染,你预分配固定数组长度 10。如果后台返回 50 条数据而你未做防护,组件可能崩溃、出错、甚至浏览器卡死。同样道理:Cloudflare 的模块未对“特征数超限”做优雅处理。

4. 配置文件传播 &波动故障表现

  • 是什么:这个特征文件每几分钟生成并推送到全球代理节点。因为部分数据库节点更新了权限,部分节点生成了“坏”文件、部分仍在生成“正常”文件,所以代理节点有时收到坏版、有时好版,造成“间歇性恢复—再失败”的现象。
  • 出错了怎样:这个传播机制导致错误不是一次性崩溃,而是“反反复复—恢复—再失败”。使得故障排查更困难,因为初期看起来像间歇性负载问题或外部攻击。
  • 类比(前端):如果你的前端有多个微前端模块部署在不同服务器,配置 JSON 每 5 分钟同步一次。由于有版本不一致,部分用户加载的是新版、部分用户加载旧版。旧版无错、新版有错,用户体验上看到有用户正常、有用户挂掉。排查起来异常“间断”而不是持续。类似情况。

5. 影响范围扩展机制

  • 是什么:因为 Bot Management 模块是核心 proxy 流程的一部分,所以很多下游服务(如 Workers KV、Access、Dashboard)也受牵连。代理模块先崩,然后其他服务因为依赖这个代理而出现问题。
  • 类比:一个你开发的 React 应用依赖一个内部 API 服务;若该服务的输入处理模块崩溃,那么不只是一个页面挂了,多个页面、组件都会挂或者显示错误。Cloudflare 的代理类似那“公共内部服务”,多数客户流量都走它

故障架构与错误流程示意图

一、整体架构简图

┌──────────────────────────────┐ │ 用户浏览器 / 客户端 │ └───────────────┬──────────────┘ │ HTTPS 请求 ▼ ┌────────────────────────────────┐ │ Cloudflare Edge (FL/FL2) │ │ ┌──────────────────────────┐ │ │ │ TLS/HTTP 层 │ │ │ └───────────────┬──────────┘ │ │ │ │ │ ▼ │ │ ┌────────────────┐ │ │ │ Core Proxy │ <───┐│ │ └───────┬────────┘ ││ │ │ ││ 特征文件加载 │ ▼ ││ │ ┌─────────────────────┐ ││ │ │ Bot Management 模块 │◀────┘│ │ └───────┬────────────┘ │ │ │判断请求是否合法 │ │ ▼ │ │ ┌────────────────────┐ │ │ │ 缓存 / WAF / 路由等 │ │ │ └─────────┬──────────┘ │ │ │ │ │ ▼ │ │ ┌────────────────────┐ │ │ │ 源站 (Origin Server)│ │ │ └────────────────────┘ │ └───────────────────────────────────┘

二、特征文件生成与分发流程

(ClickHouse 数据库) ┌────────────────────────────────┐ │ default 库 r0 库(底层分片) │ └───────────┬────────────────────┘ │ 查询列元数据 ▼ ┌─────────────────────────┐ │ 特征文件生成器(Cron) │ │ - 每隔几分钟生成一次 │ │ - 理论特征数 ~60 │ └───────────┬───────────┘ │ ▼ ┌─────────────────────┐ │ 特征文件 feature.cfg│ │ (本次事故:行数过多) │ └───────────┬─────────┘ │ 广播同步 ▼ ┌─────────────────────────┐ │ 推送至全球各 Edge 节点 │ └─────────────────────────┘

三、错误触发链示意图

1. 更改了 ClickHouse 权限逻辑 2. 查询列元数据时出现 "default + r0" 双倍列 3. 特征文件膨胀(重复字段、行数>200) 4. Edge 代理加载 feature.cfg 5. Bot Management 初始化预分配内存(限制:200 特征) 6. 检查时发现特征数过多 → panic() 7. FL2 代理线程崩溃 → 返回 5xx 8. 节点间同步推送导致反复: 好文件 → 正常几分钟 → 坏文件 → 再次崩溃 9. 大量网站受影响

四、故障时 Edge 上的表现

┌───────────────────────────────┐ │ Edge(FL2) 接收到超大 feature.cfg │ └───────────────┬───────────────┘ ▼ ┌──────────────────────────────┐ │ Bot Management 初始化 │ │ - 预期特征数 ≤ 200 │ │ - 结果发现远超限制 │ └───────────────┬────────────┘ ▼ ┌─────────────────────┐ │ panic → 代理模块崩溃 │ └─────────┬───────────┘ ▼ 返回用户 5xx / 请求失败

三、重点留意的教训

  • 自动化配置生成注意边界:即便是后台或平台层面的配置,也建议加入“生成结果不超过预期规模”的检测机制。例如特征数、行数、文件大小、字段重复率。
  • 模块设计要有弹性且异常可控:当模块载入配置超出预设范围,应优雅退化(例如日志警报、回退默认配置)而不是直接程序 panic。前端中类似于组件接收意外 props 或数据,应有合理兜底机制。
  • 阶段部署与分批验证:Cloudflare 的传播机制是“全量自动推送”但在权限变更后仍用旧逻辑,导致缺少“先在少量节点验证”机制。前端开发中也常见:先灰度、先 Canary、先少量用户验证再全量。
  • 监控指标设计:不仅监控“错误率”或“5xx 响应”,还应监控“配置文件大小/生成频次/重复行数”等“非典型”指标。前端也可监控 bundle 大小、props 字段数、API 返回字段数等。
  • 降低单点失败影响:Cloudflare 的代理是核心基础设施,一旦失败影响极大。前端/全栈系统中也应思考哪些组件是“软依赖” vs “硬依赖”,尽量将核心依赖做冗余或容错。