首页
学习
活动
专区
圈层
工具
发布

昨晚 Cloudflare 的惊天故障,原因竟是一条没写全的 SQL 引发的蝴蝶效应

大家好,我是哥飞。

昨晚 Cloudflare 的故障,哥飞写了篇文章《Cloudflare 瘫痪:全球一半以上网站都挂了,大家今晚可以早点休息了》传播甚广,至今有 2.3 万+阅读。

早上看到了 Cloudflare 官方博客公布了本次事故分析文章:

https://blog.cloudflare.com/18-november-2025-outage/

哥飞尝试让 AI 使用哥飞的文风,写了篇文章来给大家解释一下。

先说结论:一个权限调整引发的蝴蝶效应

这次故障从北京时间11月18日晚上7点28分开始,持续了大约3个小时,到晚上10点半基本恢复,完全恢复是在19日凌晨1点06分。

原因不是什么黑客攻击,而是 Cloudflare 自己在调整数据库权限时,导致一个机器学习特征文件的大小翻倍,超过了系统预设的限制,从而引发了全网崩溃。

是不是听起来有点匪夷所思?一个看似无关紧要的权限调整,怎么就能把整个 CDN 网络搞挂了呢?

事情是这样的

Cloudflare 有一个反爬虫系统(Bot Management),它会用机器学习模型给每个访问请求打分,判断是不是机器人流量。这个模型需要定期更新一个「特征文件」,来应对不断变化的爬虫策略。

11月18日上午11点05分,Cloudflare 的工程师在 ClickHouse 数据库集群上做了一个权限优化——让用户能够看到他们有权访问的所有表的元数据。

这本来是个很合理的改进,为了让查询权限控制更精细。但问题来了。之前有个查询语句是这样写的:

SELECT name, typeFROM system.columnsWHERE table = 'http_requests_features'ORDER BY name;

注意到了吗?这个查询没有指定数据库名称。

在权限调整之前,它只会返回 default 数据库的列信息。但权限调整后,它开始同时返回 default 数据库和底层 r0 数据库的列信息——相当于每个列都重复出现了一次,查询结果的行数直接翻倍。

这个查询结果被用来生成反爬虫系统的特征文件。原本大约60个特征的文件,一下子变成了120多个。

致命的硬编码限制

这里就要说到一个关键设计了。Cloudflare 的反爬虫模块为了性能优化,预先分配了固定大小的内存,并且硬编码了一个上限:最多支持200个特征。

这个限制本来设得挺宽松的,毕竟实际只用60个,留了3倍多的余量。

但是,当翻倍后的特征文件中的特征数量超过200个限制时,问题就来了。Rust 代码里有个检查,如果特征数超限就会 panic(崩溃),直接返回500错误。

更糟糕的是,这个特征文件每5分钟自动生成一次,并且会快速推送到全球所有服务器。

由于权限调整是逐步推送到各个数据库节点的,所以每5分钟,根据查询落在哪个节点上,可能生成好文件,也可能生成坏文件。

这就导致了一个非常诡异的现象:系统时好时坏,一会儿恢复正常,一会儿又全面崩溃。

这种症状让工程师们一度怀疑是不是遭到了 DDoS 攻击。

巧合的是,Cloudflare 的状态页面(托管在第三方,完全独立于 Cloudflare 基础设施)恰好在这个时候也挂了,更加深了「遭受攻击」的怀疑。

影响范围

这次故障影响到了 Cloudflare 的核心服务:

CDN 和安全服务:大量返回500错误

Workers KV:大量错误

登录系统:因为依赖 Turnstile 验证码,很多人无法登录

Access:身份验证大面积失败

邮件安全:垃圾邮件检测准确性下降

值得一提的是,Cloudflare 有新旧两个版本的代理系统(FL 和 FL2)。新版本 FL2 直接返回500错误;旧版本 FL 虽然不报错,但是会给所有流量打0分,导致很多正常用户被当作机器人拦截。

修复过程

整个修复过程可以说是教科书式的应急响应:

从发现问题到基本解决,用了3个小时。在这个过程中,Cloudflare 团队尝试了各种方向,包括限流、切换账户等,最终定位到是 Bot Management 的配置文件问题。

我们能学到什么?

作为一个做技术产品的人,我觉得这个事故有几点值得我们深思:

1. 硬编码的限制要慎重

200个特征的限制看起来很宽松,但它是个硬限制,超过就崩溃。如果当时设计成超过限制只是打个日志,或者降级处理,影响就会小很多。

2. 配置变更要有验证

特征文件的大小应该有验证机制。在推送到生产环境之前,应该检查文件是否符合预期。Cloudflare 也说了,他们会「像对待用户输入一样,对自己生成的配置文件进行验证」。

3. 数据库查询要写全条件

那个没有指定数据库名的 SQL 查询,在权限变更前能工作纯属巧合。这提醒我们,写查询时要明确所有条件,不要依赖隐含的假设。

4. 渐进式发布是把双刃剑

权限调整是逐步推送的,这本来是个好做法。但在这个场景下,反而导致了时好时坏的诡异现象,增加了排查难度。

5. 错误处理不能拖垮系统

Cloudflare 发现,他们的调试和监控系统在处理大量错误时,会自动收集详细的调试信息,这反过来消耗了大量 CPU,导致延迟进一步增加。

这是个很容易被忽视的问题。

Cloudflare 的改进计划

事故之后,Cloudflare 承诺会做这些改进:

像验证用户输入一样验证所有配置文件

增加更多的全局 kill switch

避免错误报告系统消耗过多资源

全面审查所有核心模块的错误处理机制

最后说两句

作为普通开发者,我们可能没有 Cloudflare 那么大的体量,但这些经验教训同样适用。

系统的可靠性不是某个环节做得特别好,而是每个环节都不能有致命缺陷。一个看似微小的改动,在复杂系统中可能引发连锁反应。

这也是为什么我一直强调,做产品要保持谦卑。再牛的公司,再严谨的流程,都可能出现意想不到的问题。关键是要有完善的监控、快速的响应机制,以及从错误中学习的能力。

好了,今天就聊到这里。大家在做自己的产品时,也要多想想各种边界情况,不要等到出问题了才后悔。

以上文章,完全由 AI 完成,大家觉得写得怎么样?

  • 发表于:
  • 原文链接https://page.om.qq.com/page/O4DoLyhmqmm3xPiDhSq2WHwA0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。
领券