proxy_cache_valid 按状态码分组设置可精细化控制缓存时长,但需配合缓存区定义、启用缓存及确保响应可缓存三条件;匹配按顺序优先,后写覆盖前写,建议高优先级规则置前,并辅以 proxy_cache_use_stale、proxy_intercept_errors 等提升稳定性。
直接用 proxy_cache_valid 按状态码分组写,就能实现缓存时间的精细化控制。它不是“开关”,而是“计时器”——只管缓存多久,不管要不要缓存;要真正生效,还得配齐缓存区、启用缓存、确保响应可缓存。
把语义相近或运维需求一致的状态码归为一组,每组单独指定时间:
proxy_cache_valid 200 206 304 1h; → 正常响应和协商成功,内容稳定,适合长缓存proxy_cache_valid 301 7d; → 永久重定向,语义承诺长期有效,可放心缓存一周proxy_cache_valid 302 2m; → 临时重定向必须短缓存,避免用户错过上游变更proxy_cache_valid 404 30s; → 防恶意探测,缓存“不存在”结果几十秒足够,太长会掩盖新资源上线proxy_cache_valid 500 502 503 504 10s; → 后端故障类错误短时缓存,缓解雪崩,但不宜超过 1 分钟Nginx 从上到下逐行匹配,一旦命中就停止检查。所以更具体的规则建议放在前面:
proxy_cache_valid 301 7d; 和 proxy_cache_valid 302 2m; 是安全的,不会互相干扰proxy_cache_valid any 1m; 放在最前——它会提前截断所有更精确的规则200 10m,后面又写 200 5m,最终生效的是 5 分钟)缺一不可,否则 proxy_cache_valid 再精细也无效:
http 块中定义缓存区:proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g;
location 或 server 块中启用:proxy_cache my_cache;
Set-Cookie、Cache-Control: private/no-store 的响应;若需强制缓存,加 proxy_ignore_headers Set-Cookie Cache-Control;
单靠 proxy_cache_valid 不足以应对复杂场景:
proxy_cache_use_stale error timeout http_404;:缓存过期时,若后端又挂了,仍可返回旧的 404 或错误页,提升可用性proxy_intercept_errors on; + error_page 404 = @custom_404;:把大体积 HTML 错误页换成轻量静态文件,再配缓存,更省资源add_header X-Cache-Status $upstream_cache_status;:响应头里能看到 HIT/MISS/EXPIRED,直观验证是否按预期工作