报错是这么冒出来的。新栏目上线前用预热接口批量拉了一遍 URL,当时页面还没发布,边缘节点把 404 缓存了 12 小时,上线后用户和蜘蛛拿到的都是 404,源站明明返回 200。

中间走过弯路,把「purge 只清了 HTML,没清带参数的变体」当成主因,改完现象没变。

这类报错背后常见的原因有几处,逐个排除就行。预热脚本在发布之前执行,命中源站 404。也可能是CDN 对 404 也套用了默认缓存 TTL。

还有一种情况,回源 Host 被改写,源站匹配到默认站点返回 404。

动手时先对比边缘和源站的状态码

curl -sI https://www.example.com/new/ | head -3; curl -sI -H 'Host: www.example.com' https://origin.example.com/new/ | head -3

接着清掉该路径的缓存

curl -X PURGE https://www.example.com/new/

再往下把 404 的缓存时间设为 0

proxy_cache_valid 404 0s;

预热改到发布之后并校验状态码

curl -s -o /dev/null -w '%{http_code}\n' https://www.example.com/new/

恢复的判定其实很直接。边缘节点返回 200,新页面当天被蜘蛛抓取,缓存命中率回到正常水平且 404 不再驻留。

提醒一点。预热脚本要先判断状态码再决定是否缓存,把 404 预热到全网比不预热更糟。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。

作者 9823189