在 nginx 中,可以通过配置 proxy_cache_key 来过滤掉 url 中的无用统计参数。具体做法是使用 $request_uri 配合正则表达式替换函数 map 或直接在 location 块中使用变量组合,剔除如 _ga、_gid 等追踪 id,确保不同来源但内容相同的请求命中同一缓存。

如何定义并应用清理后的缓存键变量
要实现这一目标,核心在于使用 map 指令创建一个新变量,该变量基于原始 URI 进行清洗。通过设置正则匹配模式,将特定的查询参数替换为空字符串,从而生成标准化的缓存键。

server {
listen 80;
server_name example.com;
# 定义清洗逻辑:移除 _ga, _gid, utm_source, utm_medium
map $request_uri $cleaned_uri {
~^(?<base>.*?)(\?.*)?$ $base;
default $request_uri;
}
# 更精确的 map 示例,直接处理 query string
map $args $cleaned_args {
default $args;
"~*_ga=[^&]*" "";
"~*_gid=[^&]*" "";
"~*utm_source=[^&]*" "";
"~*utm_medium=[^&]*" "";
}
location / {
proxy_pass http://backend;
# 使用清洗后的 args 构建缓存键
proxy_cache_key "$scheme$proxy_host$request_uri$cleaned_args";
proxy_cache my_cache;
proxy_cache_valid 200 10m;
}
}
上述代码中,map 块定义了如何将原始 $args 转换为 $cleaned_args。当请求携带 ?id=1&_ga=123 时,$cleaned_args 将变为 ?id=1。随后在 location 中,proxy_cache_key 使用了这个清洗后的变量,确保了带有不同统计参数的相同资源路径能共享同一个缓存条目。
验证缓存命中与参数过滤效果
配置完成后,需要验证 Nginx 是否正确识别了清洗后的键并实现了缓存命中。通过观察响应头中的 X-Cache 状态以及对比不同带参请求的返回行为,可以确认过滤机制是否生效。

# 测试请求 1: 带统计参数 # curl -I "http://example.com/page?id=1&_ga=123" # 预期结果: X-Cache: MISS (首次请求) # 测试请求 2: 相同路径,不同统计参数 # curl -I "http://example.com/page?id=1&_gid=456" # 预期结果: X-Cache: HIT (命中缓存) # 测试请求 3: 不同业务参数 # curl -I "http://example.com/page?id=2" # 预期结果: X-Cache: MISS (新资源)
在实际操作中,可以使用 curl -I 发送 HEAD 请求来检查响应头。如果第二个请求返回 X-Cache: HIT,说明 Nginx 已经忽略了 _ga 和 _gid 的差异,将它们视为同一缓存对象。这种验证方式直接反映了 proxy_cache_key 的实际构成,确保统计参数确实被排除在外。
如何处理未匹配到的复杂查询参数组合
当 URL 中包含未在 map 中明确列出的其他查询参数时,Nginx 的行为取决于 map 的定义方式。若未使用默认值覆盖,这些参数将保留在最终缓存键中,可能导致缓存碎片化。
在上述 map 配置中,default $args; 语句确保了任何未被正则匹配到的参数都会原样保留。这意味着只有明确列出的统计参数会被剥离,其他业务参数(如 sort、page)仍会影响缓存键。如果需要进一步简化,可以增加更多正则规则或使用 rewrite 模块在更早阶段清理 URI,但需谨慎避免误删有效参数。











