缓存命中率低主因是请求未进入缓存池,而非后端性能差;需先通过x-cache-status确认hit/miss/bypass等状态,再检查proxy_cache_path权限、proxy_cache_valid状态码匹配、cache_key精简及bypass规则清理。

缓存命中率低不是“没配缓存”,而是请求压根没进缓存池——多数问题出在缓存未真正生效,而非后端扛不住。排查要从请求是否落地缓存开始,而不是一上来就加机器或调后端。
看 X-Cache-Status 响应头确认真实命中状态
这是最直接的判断依据。在响应头中检查 X-Cache-Status 字段:
- HIT:缓存命中,内容来自本地缓存
- MISS:请求未命中,且未写入缓存(关键!说明缓存流程中断)
- EXPIRED:缓存存在但已过期,会回源并刷新
- BYPASS:被显式绕过(如含 Cookie、$arg_nocache=1 等)
用 curl 验证:curl -I https://your-domain/path,反复观察不同请求的返回值。如果大量是 MISS 或 BYPASS,说明缓存根本没启用成功,不是命中率问题,而是配置失效问题。
查 proxy_cache_path 是否就位且可写
缓存目录没建好、权限不对、参数错位,会导致所有请求静默 fallback 到后端:
- 确认 proxy_cache_path 写在
http块顶层,不在 server 或 location 里 - 手动创建目录并赋权:
sudo mkdir -p /var/cache/nginx/my_cache && sudo chown nginx:nginx /var/cache/nginx/my_cache - 检查磁盘空间和 inodes:
df -h /var/cache/nginx和df -i /var/cache/nginx - 验证 proxy_temp_path 是否与缓存路径同文件系统;否则写缓存失败,日志报 Permission denied 或 ERR_CONTENT_LENGTH_MISMATCH
验 upstream 响应是否被缓存规则拒之门外
即使路径对、目录对,上游返回的内容也可能被 Nginx 主动跳过缓存:
- 用
curl -I查真实状态码——常见陷阱是后端返回 201、206、304,但proxy_cache_valid只写了 200 - 显式声明需缓存的状态码:
proxy_cache_valid 200 201 206 301 302 404 10m; - 检查响应头是否含
Cache-Control: no-cache、max-age=0或Set-Cookie;默认会被跳过,加proxy_ignore_headers Cache-Control Expires Set-Cookie;强制接管 - 静态资源建议设长时效:
proxy_cache_valid 200 24h;;动态接口用短时效+验证:proxy_cache_valid 200 300s;
审 cache_key 和 bypass 规则是否污染缓存键
同一个资源生成多个 key,等于缓存彻底失效:
- 精简
proxy_cache_key:去掉干扰参数,例如从"$scheme$host$uri$is_args$args"改为"$scheme$host$uri",避免?t=123456类随机参数导致 key 不一致 - 清理绕过条件:
proxy_cache_bypass $arg_nocache $http_pragma $http_authorization;,再配合proxy_ignore_headers Set-Cookie;防止后端 Set-Cookie 触发 bypass - 若业务需区分用户(如登录态),就不该缓存;若只是公共内容,必须剥离用户标识字段
不复杂但容易忽略。真正卡住缓存的,往往不是策略多高深,而是目录没权限、状态码没覆盖、key 带了随机参数这些基础项。











