Nginx在PHP-FPM故障时返回陈旧页面需精准配置fastcgi_cache_use_stale http_500-504及timeout,配合cache_path、稳定cache_key、cache_valid覆盖5xx、cache_bypass过滤敏感请求,并通过超时参数控制“死区”长度。

要让 Nginx 在 PHP-FPM 故障时仍能返回可用页面,fastcgi_cache_use_stale 不是“自动兜底开关”,而是基于明确通信失败信号的响应策略——它只在缓存已存在且后端明确异常时,才复用过期内容。
只响应真实、可验证的故障信号
PHP-FPM 崩溃本身不可见,Nginx 只能依据协议层反馈做判断。应严格限定触发条件,避免误判放大问题:
-
必配:
fastcgi_cache_use_stale http_500 http_502 http_503 http_504;—— 这些是 PHP-FPM 明确返回的错误码,可信度最高 -
推荐加:
timeout;—— 对应fastcgi_read_timeout超时,防脚本卡死无响应 -
慎用:
error;—— 仅适用于连接被拒、地址解析失败等底层网络问题;高并发下易误判,不建议单独启用 -
禁用:
invalid_header;—— 此时 Nginx 已终止处理流程,根本不会进入缓存逻辑
确保 stale 有内容可返
stale 不生成缓存,只复用已有条目。若缓存从未成功写入,降级就完全失效:
- 在
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 500 502 503 504 1m;—— 让 5xx 响应也能进缓存,stale 才有数据源
过滤不该缓存的请求,防止 stale 返回错页
登录页、带参数 URL 或含身份 Cookie 的请求一旦被缓存,stale 会把他人页面或空响应推给用户:
- 用变量标记跳过:
set $skip_cache 0; - 拦截敏感路径:
if ($request_uri ~* "/wp-admin/|/wp-login.php|/user/") { set $skip_cache 1; } - 过滤带参请求:
if ($query_string != "") { set $skip_cache 1; } - 识别登录态:
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;—— 连接建立超时,反映 PHP-FPM 进程挂死或负载过高 -
fastcgi_send_timeout 5s;—— 发送请求体超时,防写阻塞 -
fastcgi_read_timeout 8s;—— 最关键:从 PHP-FPM 读取完整响应的总时长,超时即触发 stale


















