nginx可缓存后端返回的301/302响应,但需显式配置:分别设置proxy_cache_valid 301 7d和302 2m,启用proxy_cache并定义cache_key含$args,忽略干扰头如set-cookie,且仅proxy_pass响应可缓存。

必须显式配置状态码专属缓存时长
不能靠 `proxy_cache_valid any` 或合并写法覆盖,301 和 302 必须分开设置,因为语义和缓存策略完全不同:
-
301 表示永久迁移,建议设为较长时间,例如
proxy_cache_valid 301 7d; -
302 表示临时跳转,应短时间缓存,避免掩盖上游变动,例如
proxy_cache_valid 302 2m; - 写成
proxy_cache_valid 301 302 1h;虽语法合法,但容易导致 301 缓存过短或策略混淆,不推荐
确保后端响应实际可被缓存
Nginx 默认会尊重后端返回的缓存控制头。如果后端响应带 Cache-Control: no-cache 或 Set-Cookie,Nginx 就不会缓存,哪怕你写了 proxy_cache_valid:
- 加
proxy_ignore_headers Cache-Control Expires Set-Cookie;可绕过这些限制(仅在确认不影响业务逻辑时使用) - 配合
expires 2m;或add_header Cache-Control "public, max-age=120" always;强制注入缓存指令 - 注意:
Vary头会导致缓存碎片化,如非必要,让后端去掉Vary: User-Agent等无关字段
启用并验证缓存机制生效
光写 proxy_cache_valid 不够,还需完整闭环:
- 确认已定义缓存区:
proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m inactive=60m; - 在 location 中启用:
proxy_cache my_cache; - 确保请求走的是
proxy_pass(而非 rewrite 或 return),只有 proxy_pass 的响应才受 proxy_cache 控制 - 调试时加
add_header X-Cache-Status $upstream_cache_status;,用curl -I检查是否返回HIT
别忘了 cache_key 是否包含关键变量
如果重定向逻辑依赖请求参数(比如 ?from=mobile),而你的 proxy_cache_key 没包含 $args,不同参数可能命中同一缓存项,造成跳转错乱:
- 默认 key 是
$scheme$proxy_host$uri,不含参数 - 建议显式定义:
proxy_cache_key "$scheme$proxy_host$uri$is_args$args"; - 若需区分 Host 或其他头,也应加入 key,避免跨域名缓存污染











