nginx 官方不支持 fastcgi_cache_revalidate 指令;正确做法是通过 fastcgi_cache_use_stale 配合 last-modified/etag 与 if-modified-since/if-none-match,使 nginx 自主返回 304 并绕过 php。

Nginx 官方并不支持 fastcgi_cache_revalidate 这个指令——它根本不存在于任何稳定版 Nginx 的核心或 FastCGI 模块中。这是一个长期被误传的概念,常出现在博客或二手配置教程里。真正能减少 PHP 处理 304 请求、提升动态响应性能的,是 让 Nginx 自主判断并返回 304,全程绕过 PHP,而不是靠所谓“revalidate”去反复校验。
✅ 让 Nginx 直接返回 304,不碰 PHP
要实现客户端发起 If-Modified-Since 或 If-None-Match 请求时,Nginx 不转发给 PHP、而是自己比对后直接返回 304,需满足三个硬性条件:
- PHP 脚本必须输出标准缓存标识头(至少其一):
Last-Modified: Wed, 29 Jun 2026 10:00:00 GMTETag: "a1b2c3d4"
- Nginx 缓存配置必须保留这些响应头:
- 确保没写
fastcgi_ignore_headers Last-Modified ETag; - 默认情况下,FastCGI 缓存会保存所有响应头,无需额外开启
- 确保没写
- 缓存本身未过期(仍在
inactive时间窗口内),且请求头与缓存头匹配
只要这三点成立,Nginx 在缓存命中时就会自动比对时间戳或 ETag,并直接返回 304 —— PHP 进程完全不启动。
⚙️ 关键配置项:fastcgi_cache_use_stale
这个指令不是为“revalidate”服务的,而是兜底容错机制,但它对稳定性至关重要:
- 启用后,当 PHP 临时不可用(如超时、502、504),Nginx 可继续用旧缓存响应用户
- 特别推荐加上
updating参数:
fastcgi_cache_use_stale error timeout http_500 http_502 http_503 http_504 updating;
其中 updating 表示:当缓存即将过期、Nginx 正在后台静默刷新时,仍可用旧内容响应,避免用户感知卡顿或错误。
? 缓存基础配置不能漏
以下几项是启用有效 FastCGI 缓存的前提,缺一不可:
- 在
http{}块中定义缓存路径:fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=phpcache:128m inactive=1h max_size=2g;
- 在
location或server中启用缓存:fastcgi_cache phpcache; fastcgi_cache_valid 200 302 1h; fastcgi_cache_valid 301 1d; fastcgi_cache_valid any 1m; fastcgi_cache_key "$scheme$request_method$host$request_uri";
注意:fastcgi_cache_key 应包含影响响应的变量(如 $args 若有查询参数),否则不同参数可能命中同一缓存。
? 常见导致 304 失效的陷阱
- PHP 输出了
Cache-Control: no-cache或Pragma: no-cache→ Nginx 默认会忽略缓存(除非显式用fastcgi_ignore_headers放行,但不推荐) - 使用了
session_start()且未设置session.cache_limiter = ''→ PHP 自动加Cache-Control: private,干扰缓存行为 - Nginx 配置中误写了
fastcgi_ignore_headers Last-Modified ETag→ 直接丢弃关键头,无法做 304 判断 - 缓存
inactive时间设得太短(如10s),导致刚缓存就失效,频繁回源
不复杂但容易忽略











