必须构建“存得住、算得稳、进得去、判得准”闭环:必配fastcgi_cache_use_stale http_500-504,配合fastcgi_cache_path、稳定fastcgi_cache_key、fastcgi_cache_valid覆盖5xx、fastcgi_cache_bypass过滤敏感请求,并通过超时参数控制触发时机。

要让 Nginx 在 PHP-FPM 异常时自动返回陈旧缓存页面,不能只写 fastcgi_cache_use_stale 就完事。它必须和缓存存储、键生成、过期策略、请求过滤等环节协同工作,形成一个“存得住、算得稳、进得去、判得准”的闭环。
精准启用可信的触发条件
PHP-FPM 崩溃最可靠的信号是明确返回 5xx 状态码或读取超时,Nginx 不会感知进程是否“崩溃”,只响应协议结果或通信异常:
-
必配:
fastcgi_cache_use_stale http_500 http_502 http_503 http_504;——这些是上游明确出错的 HTTP 证据 -
推荐加:
timeout;——对应fastcgi_read_timeout超时,防 PHP 卡死不响应 -
慎用:
error;仅适用于连接被拒、地址无法解析等底层故障;高并发下易误判,不建议单独使用 -
禁用:
invalid_header——它发生在响应头解析阶段,Nginx 直接终止流程,根本不会走到缓存逻辑
确保缓存“真实存在且稳定”
stale 不生成缓存,只复用已存在的过期内容。若缓存从未存入,或 key 总在变,降级就完全失效:
- 在
http{}块中声明缓存区:fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=phpcache:100m inactive=30m use_temp_path=off; - 缓存 key 必须剔除动态字段:
fastcgi_cache_key "$scheme$request_method$host$request_uri";(删掉时间戳、用户 ID、随机参数) -
fastcgi_cache_valid必须覆盖错误响应:fastcgi_cache_valid 200 301 302 10m; fastcgi_cache_valid 500 502 503 504 1m;——否则 5xx 根本不进缓存,stale 永远无数据源
跳过不该缓存的敏感请求
未过滤的登录页、带参数 URL 或含 Cookie 的请求,会污染缓存,导致 stale 返回他人页面或空响应:
- 用变量拦截:
set $skip_cache 0; - 路径过滤:
if ($request_uri ~* "/wp-admin/|/wp-login.php|/admin/") { set $skip_cache 1; } - 参数过滤:
if ($query_string != "") { set $skip_cache 1; } - Cookie 过滤:
if ($http_cookie ~* "wordpress_logged_in|PHPSESSID|auth_token") { set $skip_cache 1; } - 绑定到 location:
fastcgi_cache_bypass $skip_cache;和fastcgi_no_cache $skip_cache;
配合超时参数控制“等待死区”长度
用户卡顿多久才触发 stale,由 fastcgi 超时参数决定。设得太长,stale 没机会生效;设得太短,健康请求也可能被误判:
-
fastcgi_connect_timeout 3s;——建立连接超时,识别进程挂死或负载过高 -
fastcgi_send_timeout 5s;——发送请求体超时,防写阻塞 -
fastcgi_read_timeout 8s;——最关键的参数,从 PHP-FPM 读响应总时长,超时即触发stale timeout
不复杂但容易忽略。


















