Nginx反向代理缓存生效需满足四点:缓存路径权限正确、proxy_cache_valid匹配真实状态码、proxy_cache_key设计合理、location中启用proxy_buffering和proxy_cache_use_stale;任一缺失将导致缓存失效。

Nginx反向代理缓存能显著降低后端压力、提升首字节时间(TTFB)和页面加载速度,但配置错一步,缓存就形同虚设——最常见问题是proxy_cache_valid没匹配到状态码,或被Cache-Control: no-cache静默覆盖。
proxy_cache_path 必须在 http 块顶层定义,且路径权限要对
缓存不是开个开关就行,得先划出一块“地”。proxy_cache_path必须放在http块最外层(不能塞进server或location里),否则启动会报unknown directive "proxy_cache"。
-
/var/cache/nginx目录需提前创建,并确保nginx用户(通常是www-data或nginx)有读写权限:sudo mkdir -p /var/cache/nginx && sudo chown nginx:nginx /var/cache/nginx -
keys_zone=my_cache:10m中的10m是内存键区大小,不是磁盘容量;max_size=1g才是磁盘上限,超了会自动淘汰旧缓存 -
use_temp_path=off建议加上,避免缓存写入临时目录再移动,减少IO抖动 - 别用
/tmp或/dev/shm做缓存路径——重启清空、空间小、不持久
proxy_cache_valid 不生效?先看上游返回的状态码和响应头
proxy_cache_valid 200 1h只对HTTP 200生效。如果你的API返回201 Created或图片服务返回206 Partial Content,这条规则完全不触发。
- 用
curl -I http://your-backend-api/endpoint确认真实Status码 - 检查是否含
Cache-Control: no-cache或max-age=0——nginx默认尊重它,需加proxy_ignore_headers Cache-Control Expires才能强制走proxy_cache_valid - 显式列出所有要缓存的状态码:
proxy_cache_valid 200 201 206 301 302 404 10m -
proxy_cache_valid any 1m是兜底,但优先级最低,别指望它覆盖具体规则 - 别漏掉
304 Not Modified:它必须显式声明,如proxy_cache_valid 304 1h,否则每次仍要问后端
proxy_cache_key 设计不当会导致缓存污染
默认$scheme$host$request_uri不区分?v=1.2.3和?v=1.2.4,也可能把带Cookie的用户请求和无Cookie的公共响应混在一起缓存。
- 基础安全写法:
proxy_cache_key "$scheme$request_method$host$request_uri$is_args$args"; - 若需区分登录态,可加入
$cookie_sessionid等,但注意这会让缓存粒度变细、命中率下降 - 含
Set-Cookie头的响应默认不缓存,这是Nginx硬限制,无法绕过 - 若后端依赖
ETag或Last-Modified做协商缓存,务必保留proxy_set_header If-None-Match $http_if_none_match;和proxy_set_header If-Modified-Since $http_if_modified_since;
location 块里漏掉 proxy_buffering 或 proxy_cache_use_stale 就等于没缓存
缓存生效 ≠ 请求一定走缓存。比如后端超时、502、503 时,默认直接透传错误给客户端——用户看到的是错误页,而不是“上一次还能用的缓存”。
-
proxy_buffering on;:关闭会导致流式响应无法缓存(尤其 JSON API) -
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;:让出错时仍可返回旧缓存 -
proxy_cache_lock on;:防止缓存未生成时大量并发请求穿透到后端(尤其冷启动) - 别忘了加
add_header X-Cache-Status $upstream_cache_status;,方便用curl -I验证是否命中
缓存键设计、状态码覆盖、错误兜底、权限与路径初始化——这四点任何一处没对齐,缓存就只是配置文件里的几行字。最隐蔽的问题往往藏在304没配、Set-Cookie响应被拒、或/var/cache/nginx目录权限不对却无报错日志里。


















