按需域名多租户场景下Varnish缓存始终MISS问题排查
问题排查与解决方案
核心原因分析
Varnish默认缓存规则存在多个不缓存的触发条件,当前的VCL配置没有对默认规则做适配修改,是导致持续MISS的核心原因,按以下步骤排查修复:
排查步骤
1. 确认默认缓存拦截规则
Varnish原生默认逻辑会在以下场景直接跳过缓存回源:
- 请求方法不是GET/HEAD
- 请求带
Cookie头 - 请求带
Authorization头 - 后端响应带
Set-Cookie头 - 后端响应带
Cache-Control: no-cache/no-store/private、Pragma: no-cache头
2. 检查源站响应头
直接请求Caddy 8080端口对应的后端服务地址,验证返回的响应是否存在上述禁止缓存的头字段:
curl -I http://你的后端地址:3000/测试路径
修复配置
修改default.vcl文件,添加自定义规则适配业务场景:
vcl 4.0; backend default { .host = "caddy"; .port = "8080"; } # 新增vcl_recv阶段处理请求 sub vcl_recv { # 若站点无用户登录等依赖Cookie的功能,直接移除所有Cookie unset req.http.Cookie; # 若需要保留部分Cookie,可使用以下规则过滤无效Cookie # if (req.http.Cookie) { # # 移除谷歌分析等统计类Cookie # set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(__[a-z]+|_ga|_gid|_gat)=[^;]*", ""); # # 清理空Cookie # if (req.http.Cookie ~ "^\s*$") { # unset req.http.Cookie; # } # } # 不需要身份校验的话移除Authorization头 unset req.http.Authorization; } sub vcl_deliver { # Insert Diagnostic header to show Hit or Miss if (obj.hits > 0) { set resp.http.X-Cache = "HIT"; set resp.http.X-Cache-Hits = obj.hits; } else { set resp.http.X-Cache = "MISS"; } } sub vcl_backend_response { # 移除后端返回的Set-Cookie,避免触发不缓存规则 unset beresp.http.Set-Cookie; # 移除禁止缓存的Pragma头 unset beresp.http.Pragma; # 强制覆盖后端返回的私有缓存规则 if (beresp.http.Cache-Control ~ "no-cache|no-store|private") { unset beresp.http.Cache-Control; set beresp.http.Cache-Control = "public, max-age=31536000"; } set beresp.ttl = 10s; set beresp.grace = 1h; }
验证效果
修改配置后重启Varnish容器,多次访问同一静态路径,查看响应头X-Cache是否变为HIT。
如果仍有问题,可进入Varnish容器执行以下命令查看详细请求日志,定位未命中原因:
varnishlog -g request -q "ReqUrl eq '/你的测试路径'"
内容的提问来源于stack exchange,提问作者Aman Sharma
相关产品推荐
相关产品推荐

