Nginx 缓存键需用 map 指令提取 Cookie、UA、请求头、参数等维度变量,构造结构化 proxy_cache_key 实现精准缓存隔离,避免污染;map 匹配顺序重要,调试可借助 add_header 输出键值。

缓存键(proxy_cache_key)是 Nginx 缓存行为的核心,决定哪些请求能命中同一份缓存。单纯用 $uri 或 $request_uri 容易导致缓存污染——比如不同用户看到同一页面、移动端拿到桌面版资源。而 map 指令正是用来把原始请求特征“翻译”成结构化变量,再拼进缓存键,实现精准隔离。
从 Cookie 提取用户或灰度标识
很多业务需要按用户身份或灰度分组缓存(如 VIP 用户不走通用缓存)。不能直接在 proxy_cache_key 里写正则,但可以用 map 提前提取:
- 在
http块中定义:map $http_cookie $uid {<br> default "";<br> ~*uid=([^;]+) $1;<br>} - 再配合设备类型:
map $http_user_agent $device {<br> default "desktop";<br> ~*Mobile|Android|iPhone "mobile";<br> ~*Tablet|iPad "tablet";<br>} - 最终缓存键写成:
proxy_cache_key "$scheme$host$uri$is_args$args$uid$device";
这样 uid=abc + mobile 就和 uid=xyz + desktop 完全不共享缓存。
按请求头或参数注入上下文维度
语言、区域、AB 测试组等信息常藏在请求头或 URL 参数里,map 可统一收口处理:
- 从
Accept-Language截取主语言:map $http_accept_language $lang_prefix {<br> default "en";<br> ~*^zh "zh";<br> ~*^ja "ja";<br>} - 识别 AB 测试流量:
map $arg_exp $exp_group {<br> default "control";<br> "v2" "test_v2";<br> "v3" "test_v3";<br>} - 缓存键加入这些变量:
proxy_cache_key "$scheme$host$uri$lang_prefix$exp_group";
按 HTTP 方法区分缓存语义
GET 和 POST 语义不同,但默认都可能被缓存(尤其当后端误返回可缓存头时)。用 map 显式控制:
- 映射方法到缓存区或键后缀:
map $request_method $method_suffix {<br> default "";<br> GET "_get";<br> HEAD "_head";<br> POST "_post_no_cache";<br>} - 加到缓存键末尾,让 POST 请求自动进入独立槽位:
proxy_cache_key "$scheme$host$uri$is_args$args$method_suffix";
即使后端没设Cache-Control: no-cache,也能靠键隔离避免误命中。
注意匹配顺序与调试手段
map 是顺序匹配,先写的规则优先;未匹配时走 default,所以通配规则(如 ~*.)必须放最后。调试建议:
- 临时加响应头看变量值:
add_header X-Cache-Key "$scheme$host$uri$uid$device" always; - 用
curl -I观察实际生成的键,确认是否含预期字段; - 若命中率低,检查
proxy_cache_key是否含动态变量但上游返回头不稳定(如$args导致键分裂)。


















