基于Cache Control头配置Varnish 4+缓存(忽略Cookie)问题排查
Varnish缓存配置问题排查与解决方案
现有配置的核心问题
- 未遵循后端
Cache-Control头的public/max-age规则,全局强制设置TTL并清空Cache-Control,完全偏离需求 - 遇到
no-cache/no-store时,仅删除自定义头但未标记响应不可缓存,无法实现绕过缓存的要求 - 全局强制删除Cookie相关头,忽略了需求中仅在
public/max-age场景下才忽略Cookie缓存的规则 X-Force-Cache的重启逻辑可能引发请求循环,且与基于Cache-Control的核心规则冲突- 未实现缓存命中时隐藏
Cache-Control头的额外需求
修正后的VCL配置
vcl 4.1; sub vcl_recv { # 处理Authorization头,默认不缓存带授权信息的请求 if (req.http.Authorization) { return (pass); } # POST请求直接绕过缓存 if (req.method == "POST") { return (pass); } # X-Force-Cache强制缓存逻辑(保留原有需求,但不干扰核心Cache-Control规则) if (req.http.X-Force-Cache) { unset req.http.Cookie; unset req.http.Cache-Control; unset req.http.Pragma; } } sub vcl_hash { # 保留X-Force-Cache的哈希逻辑 if (req.http.X-Force-Cache) { hash_data(req.http.X-Force-Cache); } } sub vcl_backend_response { # 场景1:后端返回no-cache/no-store,绕过缓存并保留Cookie if (beresp.http.Cache-Control ~ "(no-cache|no-store)") { set beresp.uncacheable = true; set beresp.ttl = 0s; return (deliver); } # 场景2:后端返回public或max-age,忽略Cookie并缓存 if (beresp.http.Cache-Control ~ "(public|max-age=[0-9]+)") { unset beresp.http.Set-Cookie; unset bereq.http.Cookie; # 优先使用后端max-age值,若需要强制覆盖可取消下面注释 # set beresp.ttl = std.duration(std.regex(beresp.http.Cache-Control, "max-age=([0-9]+)", 1) + "s", 7d); } # X-Force-Cache强制缓存逻辑,优先级低于Cache-Control规则 if (bereq.http.X-Force-Cache) { unset beresp.http.Set-Cookie; unset bereq.http.Cookie; set beresp.ttl = 7d; unset beresp.http.Cache-Control; unset bereq.http.X-Force-Cache; } # 其他未匹配场景:默认不缓存(避免误缓存私有内容) else { set beresp.uncacheable = true; set beresp.ttl = 0s; } } sub vcl_deliver { # 缓存命中时隐藏Cache-Control头 if (obj.hits > 0) { unset resp.http.Cache-Control; set resp.http.X-Cache = "HIT"; } else { set resp.http.X-Cache = "MISS"; } set resp.http.X-Cache-Hits = obj.hits; set resp.http.Mobile = req.http.CloudFront-Is-Mobile-Viewer; set resp.http.X-Device = req.http.X-Device; # 移除可能引发循环的重启逻辑,X-Force-Cache头按需返回 if (req.http.X-Force-Cache) { set resp.http.X-Force-Cache = req.http.X-Force-Cache; } else { unset resp.http.X-Force-Cache; } }
关键调整说明
- 核心规则对齐需求:严格按照后端
Cache-Control头分支处理:- 匹配
no-cache/no-store时,标记响应不可缓存并设置TTL为0,保留所有Cookie相关头以维持会话 - 匹配
public/max-age时,删除Cookie相关头实现缓存,优先使用后端返回的max-age值(如需强制覆盖可调整TTL)
- 匹配
- 缓存命中隐藏头:在
vcl_deliver中判断obj.hits > 0(缓存命中)时,直接删除resp.http.Cache-Control - 移除危险逻辑:删除
vcl_deliver中的return(restart),避免请求循环 - 默认安全策略:未匹配任何规则的场景默认标记为不可缓存,防止误缓存私有内容
- 兼容原有强制缓存:
X-Force-Cache逻辑保留,但优先级低于核心Cache-Control规则
内容的提问来源于stack exchange,提问作者Abhishek Sharma
相关产品推荐
相关产品推荐

