nginx反向代理缓存可显著降低后端压力、提升ttfb和加载速度,但需正确配置proxy_cache_path(http块顶层定义)、proxy_cache_valid(显式匹配状态码)、proxy_ignore_headers(覆盖no-cache)及x-cache-status验证命中。

直接说结论: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,这条规则完全不触发。
排查步骤:
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
- 用
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是兜底,但优先级最低,别指望它覆盖具体规则
缓存键(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";
更严谨的场景还需考虑:
- 动态接口带用户身份?加
$http_authorization或$cookie_sessionid(但注意:这会让每个用户独占缓存,失去共享意义) - 需要忽略某些参数(如
utm_source)?用map指令预处理$args,再拼进proxy_cache_key - 避免缓存POST请求?默认不缓存,但若强行开启,务必确认
proxy_cache_methods未包含POST
如何验证缓存真正在工作,而不是“以为它在工作”
光 reload 配置不等于缓存就活了。必须从响应头和日志里找证据:
- 在
location里加add_header X-Cache-Status $upstream_cache_status;,请求时看响应头是否出现X-Cache-Status: HIT - 启用日志变量:
log_format cache '$remote_addr - $upstream_cache_status $time_local "$request" $status $body_bytes_sent';,查日志比肉眼刷页面靠谱 - 观察
Age响应头:首次请求为Age: 0,几秒后再请求变成Age: 3,说明缓存已命中且计时正常 -
EXPIRED表示缓存存在但过期,会回源;STALE才是用了过期缓存——后者依赖proxy_cache_use_stale配置,不是bug
最容易被忽略的是proxy_cache_background_update on:没开它,updating状态永远不触发,缓存过期瞬间所有并发请求全打到后端,雪崩风险极高。










