age、via 和自定义回源 header 是影响 cdn 与 nginx 协同效果的三个关键头字段:age 决定缓存新鲜度判断,via 标识链路层级防循环,自定义 header 实现精准控制与安全隔离。

Age、Via 和自定义回源 Header 是 CDN 与 Nginx 协同中容易被忽略但影响缓存命中率、链路可观测性与安全边界的三个关键头字段。它们不直接参与业务逻辑,却决定了 CDN 是否信任源站响应、能否复用缓存、以及运维排查是否高效。
Age 头:让 CDN 正确判断响应新鲜度
Nginx 默认不设置 Age 头,而 CDN(如 Cloudflare、阿里云全站加速)在回源后会根据自身缓存时间自动添加 Age。问题在于:若 Nginx 启用了本地 proxy_cache,且响应经 Nginx 缓存后再返回给 CDN,Nginx 并不会自动计算并注入 Age —— 这会导致 CDN 误判响应已“过期”,频繁发起校验型回源(If-Modified-Since / If-None-Match),尤其对小文件造成碎片化压力。
解决方法是显式透传或补全 Age:
- 若 Nginx 仅作反向代理(无本地缓存),可让 CDN 自行管理 Age,Nginx 不干预;
- 若启用了
proxy_cache,需在 location 块中启用proxy_cache_use_stale updating,并配合以下配置主动注入 Age:
add_header Age $upstream_http_age always; # 透传上游 Age(适用于 CDN 回源到另一层 CDN)
或更稳妥地由 Nginx 计算:
add_header Age $sent_http_age always; # 需配合 custom log 变量或 Lua 模块生成真实值(推荐用 OpenResty 的 ngx.now() 差值计算)
实践中,多数厂商(如腾讯云 CDN)要求源站响应中携带 Age 才启用“智能过期合并”策略,否则默认按 max-age 线性衰减。
Via 头:标识链路层级,避免循环与误判
Via 是 HTTP 标准头,用于记录请求经过的中间节点。CDN 回源时通常自带 Via(如 Via: 1.1 varnish, 1.1 cloudflare),Nginx 若未配置,会默认添加自己的 Via(如 Via: 1.1 nginx)。问题在于:
- 多个 Via 值叠加可能导致长度超限,部分老旧客户端或 WAF 拒绝处理;
- 若 Nginx 被误配为 CDN 的“下一级 CDN”,可能形成 Via 循环(如 CDN → Nginx → CDN),引发 502 或缓存污染;
- 某些 CDN 厂商(如 Cloudflare)会检查 Via 中是否含自身标识,缺失则降级为直连模式,绕过边缘优化能力。
建议做法:
- 保留 CDN 原始 Via,禁止 Nginx 覆盖:
proxy_pass_request_headers on;+underscores_in_headers off;(防止解析异常); - 禁用 Nginx 自动 Via 插入:
proxy_set_header Via ""; # 清空默认插入; - 如需标识 Nginx 角色,改用自定义头(如
X-Edge-Proxy: nginx),避免干扰标准链路语义。
自定义回源 Header:精准控制与安全隔离
CDN 厂商常通过特定 Header 向源站传递上下文,例如:
-
X-Cache: HIT/MISS(阿里云)、Cf-Cache-Status: HIT(Cloudflare)—— 用于源站日志分析缓存效率; -
X-Forwarded-For+set_real_ip_from组合还原真实用户 IP; -
X-Real-IP在多层代理中易被伪造,不建议单独依赖; -
X-CDN-Provider: aliyun或X-Forwarded-By: cloudflare—— 用于 server 块分流,实现不同 CDN 的差异化缓存策略。
关键操作原则:
- 只透传必要 Header,用
proxy_pass_request_headers off;关闭默认全透传,再逐个proxy_set_header显式放行; - 对敏感头(如
Cookie、Authorization)严格过滤,除非业务强依赖(如登录态透传),否则一律proxy_set_header Cookie "";; - 利用
map按 Header 值动态设置变量,例如:
map $http_x_cdn_provider $cdn_name {
"aliyun" "ali";
"cloudflare" "cf";
default "unknown";
}
再结合proxy_cache_key "$cdn_name:$host:$request_uri"实现缓存物理隔离。
这三个头看似微小,实则是 CDN 与 Nginx 之间“信任契约”的具象体现。调优不是堆参数,而是让每个头都承载明确意图、可验证行为、可追溯影响。











