缓存写入失败主因是proxy_cache_path与proxy_temp_path权限不足且未同文件系统;需确保nginx worker用户(如www-data)对两目录有读写权限,路径属主一致,并检查日志中“(13: permission denied)”报错。

缓存路径权限不对,缓存根本写不进去
缓存目录(proxy_cache_path指定)和临时目录(proxy_temp_path)必须由 Nginx worker 进程可读写,且两者需在同一个文件系统上。常见错误是目录属主为 root,而 Nginx 实际运行用户是 www-data 或 nginx。
典型表现:日志中出现 open() "/path/to/proxy_temp/xx" failed (13: Permission denied),甚至引发 ERR_CONTENT_LENGTH_MISMATCH。
- 检查命令:
ls -ld /var/cache/nginx /usr/local/nginx/proxy_temp和ps aux | grep nginx确认用户一致 - 修复方式:
sudo chown -R nginx:nginx /var/cache/nginx /usr/local/nginx/proxy_temp - 确认
proxy_temp_path未被注释,也未指向只读挂载点(如/tmp或/dev/shm)
缓存键设计不合理,导致内容错乱或污染
缓存键(proxy_cache_key)决定“哪些请求算同一个缓存项”。若忽略协议、主机、参数或 Cookie 差异,就会把不同用户的响应混存。
例如仅用 $request_uri,HTTPS 请求可能命中 HTTP 缓存;/api/user?id=1 和 /api/user?id=2 可能共用一个缓存条目;登录态不同的用户看到彼此数据。
- 推荐基础键:
"$scheme$host$request_uri"—— 包含协议与域名,避免跨站污染 - 带查询参数的接口务必包含
$args,否则所有?id=xxx都被当成同一资源 - 需区分用户时,显式禁用缓存:
proxy_no_cache $cookie_sessionid $arg_token;
proxy_cache_valid 不生效,不是配置没写,而是条件不满足
proxy_cache_valid 只对明确列出的状态码生效。写了 proxy_cache_valid 200 10m,但后端返回 304 Not Modified 或 201 Created,就不会缓存。
更隐蔽的是:上游响应头自带 Cache-Control: no-cache 或 Set-Cookie,Nginx 默认尊重这些头,直接跳过缓存——哪怕你写了 proxy_cache_valid。
- 排查方法:
curl -I http://backend/path查看真实状态码与响应头 - 强制覆盖上游控制头:
proxy_ignore_headers Cache-Control Expires Set-Cookie; - 安全起见,不要写
proxy_cache_valid any 1m作为兜底,它优先级最低,容易掩盖具体规则失效问题
location 块位置或匹配逻辑出错,缓存策略压根没加载
proxy_cache_path 必须放在 http 块顶层,不能塞进 server 或 location 里,否则启动报 unknown directive "proxy_cache"。
而 proxy_cache、proxy_cache_valid 等指令,必须写在真正处理请求的 location 块中。常见误配包括:
- 把缓存配置写在
server块顶层,结果被更具体的location /api覆盖 - 正则匹配写成
location ~* js$(漏了点),误中/user?name=js这类动态接口 - 单页应用中,
location /用了try_files $uri $uri/ /index.html,但没单独为/index.html关闭缓存,导致 HTML 长期不更新,JS 更新后页面逻辑错乱











