Nginx 配置反向代理缓存主要通过 proxy_cache_path 定义缓存路径,并在 location 块中使用 proxy_cache 启用缓存。该方案适合内容变动频率低的静态资源或 API 响应,风险在于可能缓存用户私有数据或导致内容更新延迟。
先说结论:Nginx 反向代理缓存能显著减少后端请求压力,但必须严格区分静态与动态内容。
- 适合:HTML 静态页、图片、CSS、JS 及变动不频繁的 API 数据。
- 先准备:规划缓存存储路径、内存层级大小及缓存键规则。
- 验收:通过响应头
X-Cache-Status确认命中状态为 HIT。
配置速用版
http {
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m;
server {
location / {
proxy_pass http://backend;
proxy_cache my_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
add_header X-Cache-Status $upstream_cache_status;
}
}
}上述配置定义了一个名为 my_cache 的缓存区域,成功响应缓存 10 分钟,404 响应缓存 1 分钟。修改配置后需执行 nginx -t 检查语法,然后执行 nginx -s reload 生效。
为什么会这样
Nginx 反向代理缓存的核心机制是将上游服务器的响应保存到本地磁盘或内存,后续相同请求直接由 Nginx 返回。
当客户端发起请求时,Nginx 根据 proxy_cache_key 计算哈希值。若缓存中存在有效文件,Nginx 直接读取并返回,状态码标记为 HIT;若不存在或已过期,Nginx 向后端发起请求,获取响应后存入缓存并返回给客户端,状态码标记为 MISS。该机制减少了网络往返和后端计算消耗,但依赖缓存键的唯一性和过期策略的合理性。
分步处理
第一步:定义缓存路径
在 http 块中添加 proxy_cache_path 指令。参数 levels=1:2 表示目录层级,keys_zone 定义共享内存大小用于存储键元数据,max_size 限制磁盘占用。
第二步:启用缓存区域
在需要缓存的 location 块中设置 proxy_cache 值为之前定义的 zone 名称。确保 proxy_pass 已正确指向后端地址。
第三步:设置缓存有效期
使用 proxy_cache_valid 针对不同状态码设置不同缓存时间。例如 200 状态码缓存较久,404 状态码缓存较短避免长期缓存无效资源。
第四步:配置缓存键
默认缓存键包含请求方法和 URI。若需区分用户或参数,可自定义 proxy_cache_key,例如包含特定 Cookie 或查询参数。注意不要将敏感信息如 Session ID 纳入缓存键导致缓存穿透。
第五步:添加调试头
配置 add_header X-Cache-Status $upstream_cache_status 以便后续验证。生产环境确认无误后可移除此 header 或限制仅内部 IP 可见。
怎么验证是否生效
使用 curl 命令发起两次相同请求,观察响应头中的 X-Cache-Status 字段变化。
curl -I https://your-domain.com/path第一次请求通常显示 MISS,表示未命中缓存且已写入。第二次相同请求应显示 HIT,表示直接从 Nginx 缓存读取。检查 Nginx 错误日志 /var/log/nginx/error.log 确认无权限错误或磁盘空间警告。若显示 BYPASS,表示请求条件触发了缓存绕过规则。
常见坑
缓存了动态内容:若后端页面包含用户特定信息(如购物车、个人中心),默认缓存会导致用户看到他人数据。解决方法是针对特定 URI 关闭缓存或使用 proxy_cache_bypass 配合 Cookie 判断。
缓存更新延迟:后端内容更新后,Nginx 仍返回旧缓存直到过期。解决方法是设置较短的 inactive 时间,或使用 proxy_cache_revalidate 配合后端 ETag 验证。
磁盘空间耗尽:未设置 max_size 可能导致缓存占满磁盘。务必在 proxy_cache_path 中限制最大大小,并监控磁盘使用率。
Cookie 导致不缓存:默认情况下,若请求或响应包含 Set-Cookie,Nginx 可能不缓存。需检查 proxy_ignore_headers 设置,确认是否忽略了 Set-Cookie 和 Cache-Control。
常见问题
如何手动清除特定缓存文件?
Nginx 开源版不支持主动 purge 特定 URL 缓存,通常等待过期或使用第三方模块 ngx_cache_purge。
缓存对 HTTPS 请求有效吗?
有效,缓存发生在 Nginx 解密之后,与客户端协议无关,只要 proxy_pass 能正常获取内容即可缓存。
为什么有时候看到 EXPIRED 状态?
表示缓存文件存在但已过期,Nginx 正在向后端请求更新内容,更新完成后会再次变为 HIT。
参考来源
- Nginx Official Documentation, Module ngx_http_proxy_module, https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache
- Nginx Official Documentation, Module ngx_http_proxy_module, https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_path