最清晰可控的方式是为不同http状态码单独配置proxy_cache_valid;nginx按状态码精确匹配,具体规则优先于any,后出现的同码配置会覆盖前者,顺序和显式性至关重要。

直接为不同 HTTP 状态码写独立的 proxy_cache_valid 指令,是最清晰、最可控的方式。Nginx 会按状态码精确匹配,更具体的规则优先于 any,后出现的同状态码配置还会覆盖前面的——所以顺序和显式性很重要。
按业务语义分组设置常用状态码
不必每个状态码都单独列,可按响应性质归类,兼顾语义与运维习惯:
-
proxy_cache_valid 200 301 302 10m;→ 成功响应和重定向通常稳定,适合中等时长缓存 -
proxy_cache_valid 404 30s;→ 防恶意扫描,“不存在”结果缓存几十秒即可,太长会掩盖新上线资源 -
proxy_cache_valid 500 502 503 504 10s;→ 后端故障类错误,短时缓存缓解雪崩,建议搭配proxy_cache_use_stale error timeout updating http_404; -
proxy_cache_valid any 5s;→ 兜底策略,确保未显式声明的状态码(如 403、410、429)也有默认缓存期;注意它不会覆盖上面已定义的状态码
对重定向做精细化区分
301 和 302 语义不同,缓存策略必须分离:
-
proxy_cache_valid 301 7d;→ 永久重定向,可长期缓存;浏览器和 CDN 也倾向信任 -
proxy_cache_valid 302 2m;→ 临时重定向,必须设短,避免用户错过上游变更 - 若上游返回的 302 带
Cache-Control: no-cache,需加proxy_ignore_headers Cache-Control;才能让上述规则生效 - 重定向路径含查询参数(如
/old?ref=a → /new?ref=a),记得用proxy_cache_key $scheme$proxy_host$request_uri;或显式包含$args
确保缓存真正生效的硬性前提
proxy_cache_valid 单独存在是无效的,以下三项必须同时满足:
- 在
http块中定义缓存区:proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g; - 在
location中启用该区:proxy_cache my_cache; - 上游响应本身要“可缓存”:默认不缓存带
Set-Cookie、Cache-Control: private/no-store或Pragma: no-cache的响应;必要时用proxy_ignore_headers Set-Cookie Cache-Control;强制忽略
利用作用域层级实现精细覆盖
Nginx 支持在不同配置块中重复使用 proxy_cache_valid,以最近的作用域为准:
- 全局基础策略(
http块):proxy_cache_valid 200 5m; any 1m; - 特定接口覆盖(
location /api/):proxy_cache_valid 200 30s; 500 5s; - 结果:该路径下 200 缓存 30 秒、500 缓存 5 秒;其余未覆盖状态码仍走
http块的any 1m
验证是否按预期工作
调试阶段建议加一行头标识,直观判断缓存行为:
- 添加:
add_header X-Cache-Status $upstream_cache_status;→ 响应中会出现HIT、MISS、EXPIRED或BYPASS - 用
curl -I http://host/path多次请求,观察X-Cache-Status变化和响应时间下降 - 注意:浏览器对 301 有强本地缓存,测试时优先用
curl绕过干扰











