概述
源站故障不必直接变成用户可见的故障。如果缓存中存在有效副本而源站返回 5xx 或超时,代理可以继续返回该副本并在后台重试。这是用新鲜度换可用性,适合公开的、变化不频繁的内容,不适合余额、库存或个性化数据。
步骤
- 配置缓存区,并声明哪些上游故障允许使用过期副本:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=web:100m inactive=7d;
location / {
proxy_cache web;
proxy_cache_valid 200 10m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_background_update on;
proxy_cache_lock on;
}
- 在响应头中给下游缓存设定明确窗口:
add_header Cache-Control "public, max-age=60, stale-while-revalidate=600, stale-if-error=86400" always;
- 预热缓存后停止上游,执行
curl -sI https://www.example.com/ | grep -i -E "HTTP/|x-cache-status"。 - 统计访问日志中
STALE的比例,确认源站恢复后比例回落。
验证
预期上游停止时仍返回 200,且 X-Cache-Status 为 STALE;上游恢复后重新验证,状态变回 HIT 或 MISS。如果仍返回 5xx,检查响应是否带有 Set-Cookie 或 Cache-Control: private,这类响应不会被缓存。
注意事项
stale-if-error必须设置上限,否则过期内容可能被使用远超预期的时间。- 开启
proxy_cache_lock可避免热门键过期时大量请求同时回源。 - 只缓存 GET/HEAD,POST 请求始终直达源站。
- 持续出现 STALE 说明源站故障被掩盖,必须对过期比例设置告警而不是长期依赖。