proxy_cache_key 不支持直接使用未预处理的 $arg_xxx 等变量,必须通过 map 指令提前定义标准化变量(如 $cache_device、$cache_version)再安全引入,否则会导致缓存错乱、命中异常或碎片化。
直接说结论:
本身不支持任意自定义变量(比如
或
)直接参与计算,除非该变量已在请求处理早期被解析并稳定存在;但你可以通过
指令预定义、过滤、拼接后生成新变量,再安全地用于
。
为什么不能直接在
proxy
_cache_key 里写 $arg_device_type?
Nginx 的
在缓存查找阶段执行,而部分变量(如
、
、
)的解析依赖于请求体或 header 解析完成。若缓存逻辑早于这些变量就绪(例如发生在
前的 rewrite 阶段),Nginx 可能取到空值或默认值,导致缓存 key 错乱甚至全量命中同一份缓存。
常见错误现象:
• 同一 URL 下移动端和桌面端资源始终返回相同缓存
• 带不同
和
的请求缓存混用
•
被截断或归一为 “-”
必须确保变量在
计算前已确定,且不随请求体或流式解析变化
、
、
、
是安全的,因为它们在 request line 解析后立即可用
多数情况下可用,但需注意空参数(
)会被视作存在,值为空字符串
用 map 指令构造可信赖的缓存维度变量
这是最稳妥的做法:在
块中用
提前声明一个“清洗后”的变量,它只基于你明确信任的输入,并做标准化处理(如小写、截断、默认值 fallback)。
例如区分设备类型:
再比如提取并标准化版本参数:
关键点:
•
是惰性求值但提前注册的,所有匹配逻辑在请求进入时即完成
• 不支持正则捕获组赋值(如
),只能用完整匹配结果或
• 若源变量未定义(如没传
参数),
为空,
会走
分支
Nginx
在宝塔面板中轻松管理Nginx高性能Web服务器。提供可视化配置反向代理、负载均衡、SSL证书及HTTP缓存功能,一键优化高并发性能,助您高效搭建稳定、快速的网站运行环境。
下载
proxy_cache_key 中如何安全组合这些变量
一旦有了
、
这类经
构造的变量,就可以放心放进
,它们值稳定、无副作用。
典型配置示例:
注意细节:
• 冒号
是人工加入的分隔符,避免
和
发生哈希碰撞
• 不要省略
—— 它是空字符串或
,能准确区分有无 query string 的请求
• 如果你用
直接拼接(不经过
),当参数缺失时 key 会变成
,而用
后是
,语义更清晰、行为更可控
性能影响很小:
•
查表是 O(1) 哈希查找,比每次正则匹配快得多
•
字符串拼接本身开销极低,瓶颈永远在磁盘 I/O 或内存 zone 查找
容易忽略的兼容性与调试陷阱
缓存 key 生效的前提是整个缓存系统已启用,且 key 变化能被正确识别 —— 很多人改了
却没清旧缓存,或没验证是否真生效。
必须重启或重载 Nginx 才能使新的
和
生效(仅 reload 不够,某些旧版本需 restart)
用
输出实际 key 到响应头,用 curl 验证是否符合预期
响应头(如
/
/
)才是 key 是否起作用的最终证据,不要只看响应内容
如果用了
,key 变化后首次请求可能触发锁等待,表现为偶发性延迟升高,不是 bug
真正复杂的地方在于:缓存 key 的设计必须和业务语义对齐。比如用户登录态、A/B 测试分组、灰度标识等,都需要在
中做前置判断并收敛为有限枚举值;随意引入高基数变量(如完整
)会导致缓存碎片化、
内存爆满、
清理失效 —— 这些问题不会报错,只会悄悄拖慢服务。
proxy_cache_key$arg_xxx$http_x_forwarded_formapproxy_cache_keyproxy_cache_key$arg_*$cookie_*$http_*proxy_pass?v=1.2?v=1.3$http_user_agentproxy_cache_key$uri$args$host$scheme$arg_*?device=httpmapmap $http_user_agent $cache_device {
~*mobile|android|iphone|ipad mobile;
~*tablet tablet;
default desktop;
}map $arg_v $cache_version {
"" "default";
default $arg_v;
}mapdefaultv$arg_vmap""$cache_device$cache_versionmapproxy_cache_keyproxy_cache_key "$scheme$host$uri$is_args$args:$cache_device:$cache_version";:mobile1.2mobile1.23$is_args?$arg_xxxmap...:mobile:map...:mobile:defaultmapproxy_cache_keyproxy_cache_keymapproxy_cache_keyadd_header X-Cache-Key "$scheme$host$uri$is_args$args:$cache_device";$upstream_cache_statusHITMISMISSproxy_cache_lock onmap$http_refererkeys_zoneinactive