Varnish缓存:移动端/桌面端缓存清理及仅缓存移动端配置求助
问题1:仅针对移动端/桌面端执行Purge或Ban操作的实现
核心逻辑:给不同设备的缓存对象打标识
要精准清除某类设备的缓存,首先要在缓存阶段给移动端、桌面端的内容分别打上设备标签,让缓存键包含设备信息,后续的Purge/Ban操作就能针对性匹配。
步骤1:识别设备类型并标记
在vcl_recv中通过User Agent判断设备,存入自定义请求头:
sub vcl_recv { # 匹配常见移动端UA,可根据业务补充规则 if (req.http.User-Agent ~ "(mobile|android|iphone|ipad|blackberry|windows phone)") { set req.http.X-Device-Type = "mobile"; } else { set req.http.X-Device-Type = "desktop"; } }
步骤2:将设备标识加入缓存键
修改vcl_hash,让缓存键包含设备类型,确保不同设备的内容分开缓存:
sub vcl_hash { hash_data(req.http.X-Device-Type); # 保留原有缓存键逻辑,如URL、Host等 hash_data(req.url); if (req.http.host) { hash_data(req.http.host); } else { hash_data(server.ip); } # 其他原有hash项按需保留 }
步骤3:执行分设备Purge操作
发起Purge请求时,携带X-Device-Type指定目标设备,同时在VCL中处理权限和匹配逻辑:
# 先定义允许执行Purge的IP列表 acl purge_acl { "127.0.0.1"; # 本地测试用,替换为实际允许的IP "your-server-ip"; } sub vcl_recv { # 之前的设备识别代码... # 处理Purge请求 if (req.method == "PURGE") { if (!client.ip ~ purge_acl) { return(synth(403, "无Purge权限")); } # 根据请求头的X-Device-Type匹配缓存对象 set req.http.X-Cache-Tag = req.http.X-Device-Type; return(purge); } }
- 清除移动端缓存:发送Purge请求时添加
X-Device-Type: mobile - 清除桌面端缓存:发送Purge请求时添加
X-Device-Type: desktop
步骤4:执行分设备Ban操作
Ban操作可直接通过命令行或VCL触发,匹配设备标识即可:
- 封禁移动端指定路径缓存:
varnishadm ban "req.http.X-Device-Type == 'mobile' && req.url ~ '^/article/'" - 封禁桌面端指定路径缓存:
varnishadm ban "req.http.X-Device-Type == 'desktop' && req.url ~ '^/product/'"
也可在VCL中通过请求头触发Ban:
sub vcl_recv { # 之前的代码... if (req.method == "BAN") { if (!client.ip ~ purge_acl) { return(synth(403, "无Ban权限")); } if (req.http.X-Device-Type) { ban("req.http.X-Device-Type == " + req.http.X-Device-Type + " && req.url ~ " + req.http.X-Ban-Url); } else { ban("req.url ~ " + req.http.X-Ban-Url); } return(synth(200, "Ban规则已添加")); } }
问题2:仅缓存移动端UA,桌面端绕过缓存的VCL配置调整
核心修改:在vcl_recv中判断设备类型,桌面端直接跳过缓存逻辑
以下是调整后的关键代码(可替换原有缓存逻辑):
# 定义移动端UA匹配规则,按需扩展 acl mobile_ua { "~mobile"; "~android"; "~iphone"; "~ipad"; "~blackberry"; "~windows phone"; } sub vcl_recv { # 1. 标记设备类型 set req.http.X-Device-Type = "desktop"; if (req.http.User-Agent ~ mobile_ua) { set req.http.X-Device-Type = "mobile"; } # 2. 桌面端直接绕过缓存,转发到后端 if (req.http.X-Device-Type == "desktop") { return(pass); } # 3. 移动端执行原有缓存逻辑,保留你业务的缓存规则 if (req.method != "GET" && req.method != "HEAD") { return(pass); } if (req.http.Authorization || req.http.Cookie) { return(pass); } return(hash); # 进入缓存查找流程 } # 可选:确保移动端缓存键包含设备标识,避免跨设备缓存混淆 sub vcl_hash { hash_data(req.http.X-Device-Type); hash_data(req.url); if (req.http.host) { hash_data(req.http.host); } else { hash_data(server.ip); } } # 原有vcl_backend_response、vcl_deliver等逻辑保持不变即可
说明:
return(pass)会让桌面端请求直接跳过缓存层,永远从后端获取最新内容- 移动端会正常走你原有的缓存规则,比如静态资源TTL、缓存条件等
内容的提问来源于stack exchange,提问作者Gourav gaur
相关产品推荐
相关产品推荐

