OpenRouter 故障复盘:缓存失效压垮鉴权
缓存连接异常让 API 密钥鉴权查询涌向数据库,服务将基础设施故障表现为“401 用户不存在”,误导客户端处理。文章指出缓存失效与恢复阶段都需验证数据库承压能力和错误语义。
AI 深度解读
OpenRouter 在 2026 年 2 月的故障,暴露了缓存背后的两个问题:缓存失效后,数据库接不住突然涌入的认证查询;基础设施查询失败,又被返回成了 401 User not found,让客户端误以为凭证出了问题。
这篇分析值得读的地方,是把容量和错误语义放到一起看。服务能否扛住缓存故障,不只取决于数据库撑多久,还取决于恢复过程会不会放大流量,以及客户端收到错误后会采取什么动作。
缓存挡住了流量,也可能掩盖真实容量
原文描述的故障链路很直接:API-key 认证需要查询用户信息,平时缓存承担了大量读取;缓存连接出现问题后,这些查询落到了数据库,数据库随即承受了平时看不到的负载。
问题在于,日常运行平稳,无法证明数据库有能力接住缓存失效后的全部请求。缓存命中率越高,数据库平时暴露出来的压力,可能越不能代表故障时的压力。
能处理少量缓存未命中,不等于能处理所有请求同时未命中。
恢复阶段也有风险。大量请求同时发现缓存为空,可能重复查询同一份数据,再争相回填缓存。缓存雪崩式失效后,这种集中回源会形成「惊群」(thundering herd):每个请求单独看都合理,叠加起来却足以压垮下游。
原文没有提供数据库容量、请求量、缓存命中率或恢复耗时,因此不能据此计算 OpenRouter 的容量缺口。它指出的是一条故障路径,而非一份带完整指标的压测报告。
为什么数据库超时不该变成 401
请求返回了 401 User not found,不代表用户真的不存在。
认证失败,是系统成功完成校验后,确认凭证无效;认证基础设施失败,则是系统因为数据库超时等问题,根本没能完成校验。这两种情况需要客户端采取不同动作。
如果把后一种情况包装成 401 Unauthorized,客户端可能提示用户重新登录,把 API key 标记为失效,或者触发错误方向的告警。运维人员也可能先去排查账号和凭证,而没有及时看到认证查询背后的数据库问题。
作者建议,当基础设施故障导致认证查询无法完成时,返回 503 Service Unavailable,让客户端知道服务暂时不可用。
查不到用户和没能完成查询,必须保留区别。
但状态码改对,还不够。客户端若对 503 立即密集重试,仍可能继续放大数据库压力。错误语义、重试行为和服务端限流,需要一起检查。
缓存故障测试,应该一直测到恢复结束
作者给出的测试思路,是在接近真实的并发下主动使缓存失效,再观察数据库和请求链路如何变化。
需要看的不只是服务有没有存活,还包括数据库并发是否快速上涨、回源请求是否失控、相同查询能否合并,以及重试有没有制造第二轮高峰。缓存重新填充的速度,也应受下游承载能力约束。
作者提出,熔断器和受控的缓存回填可以限制数据库承受的突发流量。这些是文中给出的治理方向,原文没有展开具体阈值、实现方式或修复效果,不能当作已经验证成功的方案。
故障定位还有一条教训:首次故障同时遇到了拒绝服务攻击,增加了排查难度;2 月缓存问题再次出现时,没有同样的攻击伴随,底层原因才更清楚。两个异常同时发生,不能直接证明其中一个导致了另一个。
我的判断
这篇分析最有价值的地方,是提醒团队检查「平时很少走到的降级路径」。缓存正常时,认证查询的性能数据很好看;缓存失效后,这条路径才真正接受容量检验。
不过,当前输入更像一份复盘摘要。作者没有给出完整监控曲线、配置、对照实验,也没有明确修复前后的量化变化。因此,熔断和受控回填应被视为合理建议,效果仍需在具体系统里验证。
扩容数据库能够增加余量,却未必能解决重复查询和无节制重试;只修正状态码,则改善了客户端判断,仍挡不住集中回源。两类措施处理的是不同问题,需要分别验证。
能拿来做什么
- 如果 Node 服务用缓存支撑 API-key 或会话查询,可以在接近真实并发下清空缓存,记录回源速率、数据库并发和恢复耗时,别只测单个请求能否成功降级。
- 检查认证接口的异常映射,确保凭证无效与数据库超时走不同分支;前端也应分别处理
401和503,避免服务故障直接触发退出登录。 - 检查同一认证信息的大量并发未命中能否合并,并为回源和缓存回填设置并发约束,验证数据库饱和前能否拒绝部分工作。
- 联调客户端与服务端的重试策略,观察故障恢复时总请求量是否继续上涨,把恢复阶段也纳入验收。