源站已经故障,CDN 却没有切换?排查健康检查、回源故障转移与缓存掩盖
本内容发表于:2026-11-05 09:56:26
浏览量
1043

CDN 缓存通过主备两条路径连接源站,心跳探测仪帮助识别故障与切换条件。

源站维护后,监控显示主机异常,但 CDN 没有按预期切到备用站。也可能首页还能打开,登录和下单却已经失败。排查这类问题,先别急着缩短探测间隔:需要确认你配置的是独立健康检查、负载均衡调度,还是按真实回源请求触发的故障转移。

它们不是同一种机制。缓存命中还可能让一部分访问暂时不触及故障源站,造成不同用户、路径和节点看到的结果不同。本文给出配置核对与演练方法,未在你的生产环境实测;涉及切换的操作应先在预发布环境完成。

明确“切换”到底发生在哪一层

画出浏览器、CDN、源站组、负载均衡和应用的实际链路。列出主备地址、触发方式、允许的方法、错误条件、超时与重试预算,确认故障转移规则绑定在当前请求匹配的分发行为上。

一个发告警的健康检查,不一定会自动修改流量去向。Cloudflare 的独立 Health Checks 与流量调度功能需要按其产品配置分别核对,不能看到探测告警就认定备用池已经接管。[2]

CloudFront 源站组则有基于回源失败的切换机制。它只对 GET、HEAD、OPTIONS 请求执行源站故障转移,不会因为 POST 失败就按相同方式切到备用源站;文档还说明其请求处理以主源站优先,并非一次失败后就永久改用备用源站。[1]

因此,静态图片切换成功,不代表创建订单的请求也有同样的高可用保障。写业务需要应用层的状态一致性、幂等与恢复设计,不能用扩大重试或强制跨站重放代替。

缓存命中会遮住源站故障

已有对象仍可从边缘缓存返回时,主源站故障不一定立刻表现为页面失败。另一方面,未命中的资源、过期对象和不缓存的接口可能已经开始报错。部分产品还有按条件提供陈旧内容的能力,是否生效取决于具体策略。[3]

检查请求的缓存状态、Age、源站日志和回源计数。单个响应头只能提供线索,多层代理可能添加或改写它;要确认这一跳是否真的访问了主站或备站。

不要在生产全站清缓存来“证明源站坏了”。这会扩大回源流量,并让本来依靠缓存维持的访问一起失败。应使用受控的小型测试对象与明确的缓存行为,按最小范围验证。

随机查询参数也未必绕过缓存,因为缓存键可能忽略它。客户端发送 Cache-Control: no-cache 也不能被当作跨产品通用的直达源站开关;应以当前边缘配置与日志为准。

健康检查可能只测到了一个空壳

若探测路径只是静态首页,反向代理能返回 200,而数据库、认证或关键服务已不可用,监控仍可能显示健康。反过来,把每个非关键依赖都纳入就绪检查,又可能造成整组源站被同时摘除。

区分存活检查与就绪检查:前者关注进程是否需要重启,后者关注实例是否适合承接相应流量。为关键业务设计轻量、只读、低成本的检查,不在探测中创建订单、扣款或反复执行重型查询。

核对探测方法、路径、期望状态码、响应内容、Host、TLS 服务名和证书验证。探测请求跟随到了登录页再得到 200,也可能是误报健康。业务路由依赖特定 Host 时,直接访问 IP 的探测未必覆盖真实虚拟主机。

返回内容可包含不敏感的就绪标记,但不要暴露数据库密码、内部拓扑或调试栈。为探测端点限制成本与访问策略,不能为了让监控通过而开放真实业务权限。

真正触发的错误是否在规则里

应用发生业务故障时可能仍返回 HTTP 200,只在 JSON 中写入错误码。按状态码触发的源站故障转移通常不会因此自动执行。应检查接口契约与网关行为,避免把所有业务失败都包装为成功响应。

CloudFront 支持选择特定错误状态作为源站组切换条件,连接故障与超时的处理还受相关配置影响。[1] 不要推断任意 4xx 都应切换:权限不足、参数错误或资源不存在,可能在备用站同样发生,切换反而放大负载或泄露架构差异。

连接等待、读取等待、重试次数以及客户端总超时也需要一起核算。若客户端先放弃,备用站稍后响应正常,用户仍会看到失败。盲目拉长所有等待时间只会增加占用,不会修复触发条件错误。

备用站必须具备真实服务能力

检查备站的路由、证书、回源 Host、访问控制、静态版本与业务依赖。备站直接测试正常,不代表从 CDN 出口访问也正常;防火墙、私有源站认证和证书服务名都可能造成差异。

只读内容也要核对版本与对象路径。写业务还涉及数据库复制延迟、会话、库存、上传文件和消息队列。不能仅因备用主机有一个 200 健康端点,就宣布业务已经具备跨站容灾能力。

有些故障属于共享依赖,例如两个站点使用同一个数据库或认证服务。切流无法修复共同依赖故障,反而可能制造额外重试。需要明确每一种故障由切流、降级还是暂停写入处理。

用受控请求验证路径,不跳过 TLS 校验

以下 Bash 示例只适用于已授权、可直连的预发布源站,用主机名保持 Host 与 TLS 服务名一致。把保留示例地址替换成自己的测试源站:

curl -sS --max-time 10 \
  --resolve origin-test.example.com:443:192.0.2.10 \
  -D probe-headers.txt -o probe-body.txt \
  'https://origin-test.example.com/readyz'

不要加 -k 把证书错误隐藏掉。这个请求不会经过 CDN,不能用来证明边缘故障转移已经生效。它只能验证该测试机到指定源站的连接、TLS 与对应路径响应。

私有源站若只允许 CDN 访问,直连失败可能完全符合设计,不要为运行示例临时开放公网。应使用被授权的内部探测位置或供应商诊断能力,避免把认证令牌写入命令历史和公开日志。

演练要覆盖失败、接管与恢复

先备份当前源站组、探测和超时配置,安排预发布或维护窗口,指定负责人及停止条件。用测试资源模拟主源站连接失败、读取超时、指定错误状态、探测正常但业务失败等情况,分别记录行为。

验收时同时查看客户端结果、主备源站日志与数据一致性。确认请求方法符合产品切换条件,备用站实际接到了请求,且没有因缓存命中误判成功。不要在生产订单或支付接口上注入故障。

恢复主站后,继续观察请求是否重新优先访问主站、是否产生主备抖动,以及旧错误响应是否仍在缓存。若需要清理错误缓存,应限定对象与影响范围,避免用全站刷新掩盖恢复过程。

回滚时恢复已验证的路由和探测配置,但不要把流量强行送回仍然故障的主站。涉及写入的主备恢复还需检查数据与业务状态,不能只改一个 DNS 记录就结束演练。

最终要把证据落在四处:请求是否回源、故障是否满足触发条件、备用站是否具备响应能力、客户端是否等得到结果。逐项确认,比单纯提高探测频率更能解释“为什么没有切换”。

参考资料

资料核验日期:2026 年 11 月 5 日。功能、请求方法限制及超时行为以当前产品文档和实际配置为准。

  1. CloudFront:Optimize high availability with origin failover

  2. Cloudflare:Health Checks

  3. RFC 9111:HTTP Caching