nginx 默认将 vary 响应头声明的请求头(如 user-agent)自动纳入缓存键,导致不同值请求命中不同缓存或不缓存;vary: * 直接禁用缓存;可通过 proxy_ignore_headers vary 禁用或 proxy_cache_key 自定义键规避。

排查 proxy_cache 受 Vary 响应头影响的问题,核心在于理解 Nginx 如何将 Vary 值纳入缓存键(cache key)计算——它会让原本相同的请求因客户端发送的不同请求头而命中不同缓存项,甚至完全不缓存。
确认 Vary 是否被 Nginx 纳入缓存键
Nginx 默认会把 Vary 响应头中声明的请求头字段(如 User-Agent、Accept-Encoding)自动加入缓存键。也就是说,只要后端返回了 Vary: User-Agent,Nginx 就会为每个不同的 User-Agent 单独存一份缓存。
- 检查后端响应是否带
Vary:用curl -I http://backend/api查看响应头 - 确认 Nginx 是否启用该行为:默认开启,无需额外配置;禁用需显式设置
proxy_ignore_headers Vary; - 注意:
Vary: *会被 Nginx 视为“禁止缓存”,直接跳过存储(即使proxy_cache_valid已设)
验证缓存命中率是否被 Vary 拉低
如果发现缓存命中率(MISS 高、HIT 极低),且后端大量返回 Vary,大概率是它在起作用。
安全更新和维护 CLI Proxy API(CPA)部署与配置。用于 CPA 镜像升级、配置变更、认证目录兼容修复、上线验证与回滚。适用于用户提到“CPA 更新/升级/配置改了/容器重建/回滚”等场景。
- 开启缓存日志:在
location块加log_format cache '$upstream_cache_status ...';,观察 access log 中MISS是否集中在不同User-Agent或Accept值 - 用相同请求头重复 curl(加
-H "User-Agent: test"),看第二次是否变成HIT;换一个 UA 再试,若仍是MISS,说明 Vary 生效 - 临时屏蔽 Vary:加
proxy_hide_header Vary;+proxy_ignore_headers Vary;,重启并对比命中率变化
安全地绕过或控制 Vary 影响
不建议直接删掉 Vary(可能破坏后端逻辑),更推荐按需收敛或覆盖。
- 若只需按内容缓存,忽略客户端差异:用
proxy_cache_key $scheme$proxy_host$request_uri;强制固定键(但要确保后端响应内容与 UA/编码无关) - 若只关心压缩差异,可只保留
Accept-Encoding:后端返回Vary: Accept-Encoding,Nginx 自动处理 gzip/br 分流,缓存效率仍高 - 对必须区分的场景(如移动端适配),可在 upstream 前统一规范化请求头,例如用
map把多种 UA 映射为mobile/desktop,再用proxy_set_header User-Agent $device_type;
检查常见误配导致的隐性失效
有些配置看似无关,实则让 Vary 效果放大或失效。
-
proxy_buffering off;会导致响应头未完整读取就转发,Vary 可能丢失,Nginx 无法识别,缓存行为异常 -
proxy_cache_bypass $cookie_nocache $arg_nocache;若变量未定义或为空,可能意外绕过缓存,掩盖 Vary 问题 - 使用
proxy_cache_valid 200 10m;但后端返回Cache-Control: no-cache,此时proxy_ignore_headers Cache-Control;才能让规则生效——Vary 同理,它也受 ignore 控制










