FastCGI缓存失效主因是fastcgi_cache_key与fastcgi_ignore_headers配置不当;需手动创建带两级子目录的缓存路径并授权,key须含$args且避免cookie/UA,ignore_headers必须显式禁用Cache-Control等头,cache_valid须在location块中精确配置。

FastCGI缓存配错一步就完全不生效,不是开关没开,而是fastcgi_cache_key和fastcgi_ignore_headers没对上——90% 的“缓存不命中”问题都出在这两个地方。
缓存路径必须手动创建且权限正确
配置里写了fastcgi_cache_path /tmp/wpcache levels=1:2 keys_zone=wpcache:10m;,但 Nginx 不会自动建目录,更不会帮你赋权。一旦路径不存在或 worker 进程(如 www-data)无写权限,缓存静默失效:open() "/tmp/wpcache/" failed (13: Permission denied) 只会在 error.log 里轻描淡写出现一次,nginx -t 完全不报错。
- 先执行:
sudo mkdir -p /tmp/wpcache/{temp,levels}(注意:levels=1:2要求两级子目录结构存在) - 再授权:
sudo chown -R www-data:www-data /tmp/wpcache(确认你的 worker 用户名,可用ps aux | grep nginx查) -
max_size别设满磁盘,建议取可用空间的 10%~20%,避免填满根分区引发系统级故障
fastcgi_cache_key 必须稳定且覆盖业务变量
默认的 $scheme$request_method$host$request_uri 看似完整,但实际中极易导致缓存击穿或重复缓存。比如 WordPress 搜索页 /?s=nginx 和 /?s=cache 会被当成同一缓存,除非你显式带上 $args。
- 通用建议写法:
fastcgi_cache_key "$scheme$request_method$host$request_uri$args"; - 若需过滤 utm_* 类参数,不能靠
fastcgi_ignore_headers,得用map预处理$args再拼进 key - 绝对不要把
$cookie_*或$http_user_agent放进 key——除非你真要按登录态或设备做差异化缓存,否则直接废掉共享性
fastcgi_ignore_headers 是缓存生效的硬开关
PHP 脚本、Laravel 中间件、WordPress 插件常输出 Cache-Control: no-cache 或 Set-Cookie,Nginx 默认会尊重这些响应头并跳过缓存——哪怕你写了 fastcgi_cache_valid 也无效。
- 必须显式禁用:
fastcgi_ignore_headers Cache-Control Expires Set-Cookie; - 如果后端用了
X-Accel-Expires控制缓存时长,它会覆盖fastcgi_cache_valid,此时要加fastcgi_hide_header X-Accel-Expires;才可控 -
fastcgi_cache_use_stale error timeout http_500;建议加上,让出错时仍返回旧缓存,防雪崩
fastcgi_cache_valid 必须在 location 块里写
fastcgi_cache wpcache; 只是启用缓存区域,真正决定“哪些状态码缓多久”的是 fastcgi_cache_valid。它漏写在 location ~ \.php$ 块里,等于整套缓存配置白搭。
- 基础写法:
fastcgi_cache_valid 200 301 302 10m;(只缓存成功响应) - 兜底策略:
fastcgi_cache_valid 404 1m;(缓存 404 减少无效查询) - 别写
fastcgi_cache_valid any 1m;——这会让 500、304 甚至重定向都进缓存,容易引发脏数据
最易被忽略的一点:所有缓存指令(fastcgi_cache、fastcgi_cache_valid、fastcgi_cache_key)都必须出现在具体的 location 块里,不能只放在 server 或 http 块顶部;而 fastcgi_cache_path 又必须放在 http 块里——层级错位,缓存就彻底失效。


















