Nginx proxy_cache_use_stale如何让504源站故障时,陈旧缓存自动降级?

2026-04-29 02:132阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计868个文字,预计阅读时间需要4分钟。

Nginx proxy_cache_use_stale如何让504源站故障时,陈旧缓存自动降级?

当源站返回504 Gateway Timeout错误时,Nginx默认会将错误直接传递给用户。但如果你已缓存过该资源,则结果如下:

为什么 504 场景下 stale 能生效

504 是明确的上游网关超时响应,属于 proxy_cache_use_stale 原生支持的触发条件之一。它和 error(连接失败)、timeout(读取超时)不同:504 表示后端已接收请求但未能按时完成,Nginx 收到的是完整 HTTP 响应包(含状态行和头),因此可安全复用历史缓存。

  • 只要该 URL 曾成功缓存过(哪怕已过期),且配置了 http_504 参数,Nginx 就会在收到 504 时立即返回陈旧副本
  • 无需等待后台更新完成,也不依赖 proxy_cache_background_update
  • 响应速度接近本地磁盘读取,通常在毫秒级,远快于重试或报错

必须配套的基础缓存配置

单独加 proxy_cache_use_stale http_504 不起作用。以下三项是硬性前提:

  • 定义缓存区:在 http 块中配置 proxy_cache_path,例如:
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:512m inactive=3d use_temp_path=off;
  • 启用并绑定缓存:在 location 中指定 proxy_cache my_cache;proxy_cache_valid,例如:
    proxy_cache_valid 200 301 302 10m;(没有这条,Nginx 不知道“多久算过期”,stale 就无从谈起)
  • 确保缓存键合理:避免因 Cookie、随机参数导致同一资源被拆成多个缓存项,推荐显式设置:
    proxy_cache_key "$scheme://$host$request_uri";(忽略 query 中的版本号等干扰参数)

如何验证 504 降级真实生效

不能只看返回码是否变成 200,要确认内容确实来自陈旧缓存:

  • 先正常访问一次目标 URL,确认缓存命中(响应头含 X-Cache: HIT 或自定义的 X-Cache-Status: HIT
  • 临时让后端返回 504:可用 iptables -A OUTPUT -p tcp --dport 8080 -j REJECT 拦截 upstream 流量,或修改 upstream server 直接 return 504
  • 再次请求,检查响应头:
    – 状态码应为 200(或其他原始成功码)
    X-Cache-Status 应为 STALE(需配合 add_header X-Cache-Status $upstream_cache_status;
    Age 响应头值应大于 s-maxageproxy_cache_valid 设定时间
  • 对比 body 内容与故障前一致,说明不是新生成,而是旧缓存复用

生产环境推荐组合写法

针对 CDN 或高可用边缘节点,建议这样写:

  • proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
    覆盖连接失败、读取超时、后台更新中、以及全部常见网关错误
  • proxy_cache_lock on;
    防止缓存失效瞬间大量并发回源压垮源站
  • proxy_cache_background_update on;
    允许前台返回 stale 的同时,后台悄悄刷新缓存,下次请求就能拿到新鲜内容
  • add_header X-Cache-Status $upstream_cache_status;
    便于监控平台识别当前响应来源(MISS/HIT/STALE/BYPASS)

不复杂但容易忽略

标签:NginxProxy

本文共计868个文字,预计阅读时间需要4分钟。

Nginx proxy_cache_use_stale如何让504源站故障时,陈旧缓存自动降级?

当源站返回504 Gateway Timeout错误时,Nginx默认会将错误直接传递给用户。但如果你已缓存过该资源,则结果如下:

为什么 504 场景下 stale 能生效

504 是明确的上游网关超时响应,属于 proxy_cache_use_stale 原生支持的触发条件之一。它和 error(连接失败)、timeout(读取超时)不同:504 表示后端已接收请求但未能按时完成,Nginx 收到的是完整 HTTP 响应包(含状态行和头),因此可安全复用历史缓存。

  • 只要该 URL 曾成功缓存过(哪怕已过期),且配置了 http_504 参数,Nginx 就会在收到 504 时立即返回陈旧副本
  • 无需等待后台更新完成,也不依赖 proxy_cache_background_update
  • 响应速度接近本地磁盘读取,通常在毫秒级,远快于重试或报错

必须配套的基础缓存配置

单独加 proxy_cache_use_stale http_504 不起作用。以下三项是硬性前提:

  • 定义缓存区:在 http 块中配置 proxy_cache_path,例如:
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:512m inactive=3d use_temp_path=off;
  • 启用并绑定缓存:在 location 中指定 proxy_cache my_cache;proxy_cache_valid,例如:
    proxy_cache_valid 200 301 302 10m;(没有这条,Nginx 不知道“多久算过期”,stale 就无从谈起)
  • 确保缓存键合理:避免因 Cookie、随机参数导致同一资源被拆成多个缓存项,推荐显式设置:
    proxy_cache_key "$scheme://$host$request_uri";(忽略 query 中的版本号等干扰参数)

如何验证 504 降级真实生效

不能只看返回码是否变成 200,要确认内容确实来自陈旧缓存:

  • 先正常访问一次目标 URL,确认缓存命中(响应头含 X-Cache: HIT 或自定义的 X-Cache-Status: HIT
  • 临时让后端返回 504:可用 iptables -A OUTPUT -p tcp --dport 8080 -j REJECT 拦截 upstream 流量,或修改 upstream server 直接 return 504
  • 再次请求,检查响应头:
    – 状态码应为 200(或其他原始成功码)
    X-Cache-Status 应为 STALE(需配合 add_header X-Cache-Status $upstream_cache_status;
    Age 响应头值应大于 s-maxageproxy_cache_valid 设定时间
  • 对比 body 内容与故障前一致,说明不是新生成,而是旧缓存复用

生产环境推荐组合写法

针对 CDN 或高可用边缘节点,建议这样写:

  • proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
    覆盖连接失败、读取超时、后台更新中、以及全部常见网关错误
  • proxy_cache_lock on;
    防止缓存失效瞬间大量并发回源压垮源站
  • proxy_cache_background_update on;
    允许前台返回 stale 的同时,后台悄悄刷新缓存,下次请求就能拿到新鲜内容
  • add_header X-Cache-Status $upstream_cache_status;
    便于监控平台识别当前响应来源(MISS/HIT/STALE/BYPASS)

不复杂但容易忽略

标签:NginxProxy