proxy_cache_valid不生效的最常见原因是未匹配响应状态码,默认仅支持200、301、302;需用curl -i确认真实状态码,显式配置如proxy_cache_valid 200 201 206 301 302 304 404 10m,并配合proxy_ignore_headers忽略cache-control等干扰头。

proxy_cache_valid 不生效,最常见原因就是它根本没匹配到响应状态码——默认只认 200、301、302,其他状态码哪怕只差一个(比如 201、206、404、304),这条规则就完全不触发。
确认上游真实返回的状态码
别猜,直接看后端实际发了什么:
- 用 curl -I http://your-backend/xxx 抓响应头,重点看第一行 Status 字段,例如
HTTP/1.1 206 Partial Content或HTTP/1.1 404 Not Found - 如果用的是 API 接口,检查返回是否是
201 Created、204 No Content这类非标准缓存码 - 浏览器开发者工具 Network 标签页也能看到 Status,但注意:有些前端框架会拦截并改写状态码,不如 curl 真实
显式列出所有要缓存的状态码
不能依赖“默认”或“大概率”,必须一条条写清楚:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 常见组合示例:
proxy_cache_valid 200 201 206 301 302 304 404 10m; - 重定向必须单列:
proxy_cache_valid 301 1d;和proxy_cache_valid 302 2m;是两回事,不能混在一条里指望通用 -
proxy_cache_valid any 1m;是兜底,但优先级最低,已有具体规则时它不会覆盖
留意 Cache-Control 等响应头的干扰
即使状态码对上了,Nginx 默认也会优先听从上游的缓存指令:
- 如果响应带
Cache-Control: no-cache、max-age=0或private,proxy_cache_valid 直接被忽略 - 解决办法是加
proxy_ignore_headers Cache-Control Expires;,强制让 Nginx 忽略这些头,转而信任你写的 proxy_cache_valid - 注意:含
Set-Cookie的响应默认不缓存,无法绕过,除非加proxy_ignore_headers Set-Cookie;(慎用,可能影响用户态)
验证缓存是否真按状态码命中
加个响应头,一眼看清结果:
- 配置里加上:
add_header X-Cache-Status $upstream_cache_status; - 连续两次请求同一 URL:
第一次返回X-Cache-Status: MISS,状态码如 404;
第二次若变成HIT且状态码仍是 404,说明 404 已成功缓存 - 再配合
curl -I观察Age头是否递增,能进一步确认缓存正在持续服务










