提升 Nginx 缓存命中率的关键是精准构造 proxy_cache_key:只保留影响响应的变量,用 map 预处理归一化参数与 Cookie,统一 Host 大小写、简化语言头,并通过日志和监控验证 key 收敛效果。

提升 Nginx 缓存命中率,核心不在加空间、也不在延时长,而在于让逻辑上“相同内容”的请求生成完全一致的 proxy_cache_key。键一乱,缓存就碎;键一准,哪怕流量翻倍,回源也能压到最低。
只留真正影响响应的变量
缓存键不是越全越好,而是越准越好。默认的 $scheme$proxy_host$request_uri 会把所有 query 参数、大小写差异、编码变体甚至空格都算进去,极易造成缓存分裂。
- 静态资源(JS/CSS/图片):用
$scheme$host$uri就够——路径不变,内容就不该变 - SSR 页面(如 Next.js):保留
lang、region、theme这类服务端渲染依赖的参数,但过滤utm_*、ref、fbclid等纯埋点字段 - 登录态页面:若需区分用户,只取关键 Cookie 字段(如
session-token),而非整段$http_cookie
用 map 预处理,避免 key 行内写逻辑
别在 proxy_cache_key 里塞正则或条件判断。所有清洗、提取、归一化动作,都用 map 提前做好,让 key 行干净、稳定、可读。
- 剥离干扰 query:
map $args $cache_args {
~^(lang=[^&]+|region=[^&]+|id=[^&]+|theme=[^&]+) $1;
default "";
} - 提取指定 Cookie:
map $http_cookie $cache_session {
~session-token=([^;]+) $1;
default "guest";
} - 最终 key 示例:
proxy_cache_key "$scheme$host$uri|$cache_args|$cache_session|$device";
归一化 Host、Scheme 和语言头
CDN 回源常因域名大小写、HTTP/HTTPS 混用、Accept-Language 标签格式不一,导致同一资源生成多个 key。
- Host 统一小写:
${host,,}(Nginx 1.11.8+ 支持) - 忽略协议差异(CDN 通常只 HTTPS 回源):
proxy_cache_key "${host,,}$clean_uri"; - 语言头只取主标签:
map $http_accept_language $lang {
~^([a-z]{2}) $1;
default en;
}
再把$lang加入 key,不直接用原始 header
验证和监控不能跳过
改完 key 不等于生效,必须验证是否真收敛。
- 加日志:配置
log_format cache_log '$upstream_cache_status $request_uri $cache_key';,抽样看相同业务请求是否生成相同 key - 手动比对:用 curl 发起带 / 不带 utm 参数的请求,检查
X-Cache-Status是否都是 HIT - 观察趋势:重点关注优化后 24–72 小时的边缘节点命中率变化,尤其对比高流量接口


















