要真正用好Nginx缓存,需理解浏览器缓存、Nginx反向代理缓存等分层机制,明确每层“谁在缓存、缓什么、怎么失效”,并规避Cookie混用、权限错误、缓存穿透等常见陷阱。

要真正用好 Nginx 缓存,不能只盯着 proxy_cache 那几行配置。它是一整套分层协作机制,从用户浏览器开始,经 CDN、Nginx 反向代理,再到应用层,每一层职责不同、控制方式不同。搞清楚每层“谁在缓存、缓什么、怎么失效”,才能避免缓存错乱、数据陈旧或压垮后端。
浏览器缓存:离用户最近、最轻量的一层
这是由 HTTP 响应头直接驱动的,Nginx 本身不生成内容,但可以精确控制这些头部。关键字段是 Cache-Control 和 ETag:
-
Cache-Control: public, max-age=3600表示该响应可被浏览器和中间代理(如 CDN、Nginx)缓存 1 小时 -
Cache-Control: private, no-store表示仅限当前用户浏览器缓存,且禁止存储敏感内容(如登录页) - Nginx 可通过
add_header或expires指令统一注入策略,例如:location ~* \.(js|css|png|jpg)$ { expires 1h; } - 配合
ETag和If-None-Match,能实现高效协商缓存,减少带宽消耗
Nginx 反向代理缓存:保护后端的核心防线
这是你主动配置、可控性最强的一层,适用于动态接口返回的 HTML 页面、API JSON 响应等。它不依赖客户端行为,而是在 Nginx 进程内完成存储与复用。
- 必须先定义缓存区:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m;
其中keys_zone是内存索引区,inactive控制未被访问的缓存自动清理时间 - 在
location中启用:proxy_cache my_cache;<br>proxy_cache_valid 200 302 10m;<br>proxy_cache_valid 404 1m;
- 注意默认不缓存带 Cookie 或 Set-Cookie 的响应,如需缓存登录态无关的接口,可加:
proxy_ignore_headers Cache-Control Set-Cookie; - 缓存键(cache key)默认包含
$scheme$proxy_host$request_uri,如需排除参数或标准化路径,用proxy_cache_key自定义
缓存刷新与主动失效:不能只靠过期时间
静态过期策略无法满足运营需求——比如商品价格改了、文章编辑发布了,必须立刻生效。Nginx 提供两种常用手段:
-
Purge 方式:配合
ngx_cache_purge模块(需编译时添加),用特定请求清除匹配 URL 的缓存:location ~ /purge(/.*) { allow 127.0.0.1; deny all; proxy_cache_purge my_cache $host$1$request_args; } -
Bypass 方式:通过请求头临时绕过缓存,适合灰度或调试:
proxy_cache_bypass $http_cache_bypass;<br>proxy_no_cache $http_cache_bypass;
客户端加Cache-Bypass: 1即可直通后端 - 更稳妥的做法是结合版本号或时间戳控制 URL,例如将
/api/v1/user改为/api/v1.0.2/user,天然规避旧缓存
常见陷阱与避坑要点
缓存配置不当,比不缓存还危险。几个高频问题务必留意:
- 不要对含用户身份信息的响应开启全局缓存,尤其
Set-Cookie或Vary: Cookie响应,否则可能把 A 用户的页面缓存后返回给 B 用户 - 默认不缓存 POST、PUT 等非安全方法,如需缓存 API 结果,需显式配置
proxy_cache_methods GET HEAD POST; - 缓存目录权限要与 Nginx 工作用户一致(如
nginx:nginx),否则写入失败却无报错,表现为“缓存始终不命中” - 高并发下缓存锁(
proxy_cache_lock)可防止缓存穿透,但会阻塞后续请求;建议搭配proxy_cache_lock_age和proxy_cache_lock_timeout细调



















