You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置Varnish 3,使其根据Vary响应头条件忽略Cookie?

当然有办法!完全不需要硬编码URI,核心思路是让Varnish根据后端ESI端点返回的Vary头动态调整缓存策略——既尊重需要区分Cookie的响应,又让无需区分的响应能被所有带Cookie的请求复用。

1. 调整缓存键生成逻辑,针对ESI子请求排除默认的Cookie

Varnish 3默认会把请求的Cookie头加入缓存键,这会导致即使后端返回Vary: Accept-Encoding,不同Cookie的请求也会生成不同的缓存键。我们需要修改vcl_hash,只给主请求(非ESI)加入Cookie,ESI子请求的缓存键不包含Cookie,交给Vary头来控制变体:

sub vcl_hash {
    # 基础缓存键:URL + 主机(或服务器IP)
    hash_data(req.url);
    if (req.http.host) {
        hash_data(req.http.host);
    } else {
        hash_data(server.ip);
    }
    
    # 仅主请求(非ESI)才将Cookie纳入缓存键
    if (req.esi_level == 0) {
        if (req.http.Cookie) {
            hash_data(req.http.Cookie);
        }
    }
}

2. 让Varnish尊重后端返回的Vary头处理变体

接下来,在vcl_fetch中确保ESI响应的Vary头被Varnish正确识别,不要修改后端返回的Vary值——这样Varnish会自动根据Vary头的内容生成缓存变体:

sub vcl_fetch {
    # 处理ESI子请求的缓存规则
    if (req.esi_level > 0) {
        # 确保响应可缓存(如果后端没设置Cache-Control,可添加默认规则)
        if (!beresp.http.Cache-Control) {
            set beresp.http.Cache-Control = "public, max-age=3600";
        }
        
        # 关键:保留后端返回的Vary头,不做修改
        # 如果后端返回Vary: Cookie, Accept-Encoding,Varnish会自动按这两个头区分变体
        # 如果返回Vary: Accept-Encoding,Varnish只会按编码区分,忽略Cookie差异
    }
}

为什么这能解决问题?

  • 对于返回Vary: Cookie, Accept-Encoding的ESI端点:Varnish会根据Cookie和Accept-Encoding生成不同的缓存变体,确保身份验证相关的响应正确区分用户。
  • 对于返回Vary: Accept-Encoding的ESI端点:Varnish只会根据编码生成变体,完全忽略请求中的Cookie差异,所以所有带Cookie的请求都会命中同一个缓存响应,无需回源。

额外注意事项

  • 确保后端返回的Vary头准确无误:这是整个策略的核心,后端必须正确返回对应场景的Vary值。
  • 如果你的主请求也需要区分Cookie,上面的vcl_hash已经处理了,主请求的缓存键会包含Cookie,不影响主请求的缓存逻辑。

内容的提问来源于stack exchange,提问作者MicE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:42:04