CDN与Nginx缓存键需逻辑对齐,确保CDN key是Nginx key的确定性子集或可推导超集;CDN宜用$host+$uri(忽略query),Nginx按业务扩展如语言、登录态等维度,并通过标准化query、注入请求头、可观测日志等手段保障一致性。

CDN 节点与 Nginx 源站的缓存键(cache key)必须逻辑对齐,否则会出现“同一请求在 CDN 命中、在 Nginx 未命中”或“缓存污染/错乱”,本质是两级缓存语义不一致。关键不是让两者 key 完全相同,而是确保:CDN 的 key 是 Nginx key 的**确定性子集或可推导超集**,且双方对“什么算同一个资源”的判断逻辑一致。
明确分层职责,避免 key 冗余冲突
CDN 应聚焦无状态、高共性的维度;Nginx 承担上下文敏感的精细化区分:
- CDN 缓存键建议只含 $host + $uri(不含 query string),适用于带哈希指纹的静态资源(如
/js/app.a1b2c3.js)——这类资源天然幂等,参数无关 - Nginx 缓存键需按业务需要扩展,例如:
动态 API 缓存:用"$scheme$host$request_uri$http_accept_language$http_cookie",区分语言与登录态
多端适配页面:加入$http_user_agent或更轻量的$arg_device - 若 CDN 需支持带参路由(如分页、筛选),则必须与 Nginx 协同白名单 query 参数,例如只保留
id和lang:set $cache_key "$host$uri?$(arg_id)&$(arg_lang)";
用请求头传递上下文,实现 key 可控映射
CDN 回源时主动注入标准化头,让 Nginx 能识别来源并复用/跳过缓存逻辑:
- CDN 回源请求加头:
X-From-CDN: true和X-CDN-Cache-Key: [cdntoken](可选,用于调试比对) - Nginx 中据此控制行为:
if ($http_x_from_cdn = "true") { set $skip_cache "1"; }
或反向利用:proxy_cache_key "$http_x_cdn_cache_key";(需 CDN 生成稳定 token) - 避免直接透传原始
$http_cookie或$http_user_agent到 Nginx key 中——这些字段长度不可控、基数高,易引发内存溢出
标准化 query string,消除等效 URL 的 key 分裂
同一语义的请求因参数顺序、大小写、空格不同产生多个 key,浪费空间且降低命中率:
- Nginx 原生不支持 query 排序,可用
map+ Lua(如ngx.var.args预处理)或前置网关统一规整 - 简单场景下,强制小写+去空格+截断非关键参数:
map $args $clean_args { ~^(.*?)(?:&|$) $1; default $args; }
再组合:proxy_cache_key "$host$uri?$clean_args"; - 对含敏感参数(如
token、sign)的请求,应在 Nginx 层proxy_cache_bypass或设 TTL=0,不进缓存
验证与监控:确保映射真实生效
光配置不够,要可观测 key 是否按预期生成:
- 在 Nginx location 中添加响应头,暴露实际计算出的 key:
add_header X-Nginx-Cache-Key "$scheme$host$request_uri$http_accept_language" always; - CDN 控制台开启“回源请求日志”,比对 CDN 发出的 URI 与 Nginx 收到的
$request_uri是否一致 - 定期用
nginx -T | grep proxy_cache_key检查最终生效的 key 表达式,防止被更高优先级 location 覆盖


















