应将 fastcgi_cache_valid 404 设为 60 秒并配合 inactive=90s 清理冷缓存,显式忽略上游禁用头,且用 fastcgi_cache_bypass 精准跳过敏感路径的 404 缓存。

直接把 fastcgi_cache_valid 设成“404 1h”反而会放大问题——404 页面缓存太久,新上线的页面用户看不到,爬虫反复扫还固化错误路径。关键不是“要不要缓”,而是“缓多久、怎么清、如何防堆积”。
给 404 显式设极短有效期(1–90 秒)
404 必须单独写规则,不能依赖 any 或漏配。Nginx 默认不缓存 404,不声明就等于不缓,起不到防刷作用;但设太长又掩盖真实状态。推荐区间:
-
fastcgi_cache_valid 404 60s;—— 平衡防探测与及时刷新,适用于多数 CMS 或博客类站点 - 高敏感场景(如刚上线新栏目)可压到
30s;流量极大且扫描频繁时可用90s,但勿超 2 分钟 - 切忌设为
0:Nginx 会忽略该指令,等效于未配置,完全失去缓存防护能力
配合 inactive 参数自动清理冷门 404 缓存
即使只缓 60 秒,大量随机路径(如 /wp-includes/xxx.php、/admin/123)仍会快速填满缓存空间。靠 inactive 主动回收:
- 在
fastcgi_cache_path中加inactive=90s,表示任意缓存项若 90 秒内无访问,立即释放 - 与 60 秒有效期形成“双保险”:过期后若无人再访,90 秒内必删;有人再访则重置计时
- 示例:
fastcgi_cache_path /cache levels=1:2 keys_zone=phpcache:100m inactive=90s use_temp_path=off;
屏蔽上游干扰头,确保规则强制生效
PHP 脚本常输出 Cache-Control: no-cache 或 Expires: -1,Nginx 默认会优先遵循这些头,导致你的 fastcgi_cache_valid 404 60s 形同虚设。必须显式覆盖:
- 在对应
location块中加入:fastcgi_ignore_headers Cache-Control Expires; - 仅对 404 场景启用此指令更稳妥,避免影响正常页面的缓存控制逻辑
- 若后端可控,建议 PHP 层统一不输出禁用缓存头,比 Nginx 层拦截更干净
用 fastcgi\_cache\_bypass 控制哪些 404 不缓
不是所有 404 都值得缓。比如后台路径、API 探测、带敏感参数的请求,缓了反而暴露结构或浪费资源:
- 定义跳过变量:
set $skip_404_cache 0; - 匹配特征并设为 1:
if ($request_uri ~* "^/(wp-admin|admin|api/v[0-9]+/health)") { set $skip_404_cache 1; } - 关联指令:
fastcgi_cache_bypass $skip_404_cache;和fastcgi_no_cache $skip_404_cache;











