Varnish集群问题:如何在所有节点共享Ban缓存清理操作?
解决Varnish集群Ban操作同步问题
免费版Varnish 6没有内置的集群缓存失效同步机制,单节点执行Ban只会清除本地缓存,要让所有节点同步Ban,可通过以下几种低成本方案实现:
方案一:用脚本批量触发所有节点Ban操作
这种方式简单直接,通过外部脚本调用varnishadm命令,给所有Varnish节点发送Ban指令:
- 编写同步Ban脚本
创建varnish_sync_ban.sh脚本,替换其中的Varnish管理地址和secret路径:
#!/bin/bash TARGET_HOST=$1 TARGET_URL=$2 SECRET_PATH="/etc/varnish/secret" # 给本地Varnish执行Ban varnishadm -S $SECRET_PATH -T 127.0.0.1:6082 ban "req.http.host == $TARGET_HOST && req.url == $TARGET_URL" # 给远程Varnish节点执行Ban(多节点可复制此行添加) varnishadm -S $SECRET_PATH -T 192.168.1.102:6082 ban "req.http.host == $TARGET_HOST && req.url == $TARGET_URL"
给脚本添加执行权限:
chmod +x /usr/local/bin/varnish_sync_ban.sh
- 修改VCL配置
替换原有的Ban逻辑,调用脚本完成多节点同步:
sub vcl_recv { # 其他原有规则... if (req.url ~ "^/app/api/client($|/.*)" && (req.method == "POST" || req.method == "PUT")) { std.syscall("/usr/local/bin/varnish_sync_ban.sh", req.http.host, req.url); std.syslog(180, "[debug][" + req.method + "] - Syncing cache purge for: " + req.http.host + req.url); return (pass); set req.backend_hint = web_node.backend(); } }
注意:确保Varnish运行用户有权限执行脚本,且远程节点的管理端口(默认6082)对外开放,两台节点的secret文件需一致。
方案二:通过HTTP端点触发远程节点Ban
利用Varnish的std.httpcall函数,向其他Varnish节点的内部HTTP端点发送Ban请求:
- 给所有Varnish节点添加内部Ban触发规则
在每台Varnish的VCL中添加一个仅允许内部IP访问的Ban触发路径:
sub vcl_recv { # 其他原有规则... # 内部同步Ban的端点,限制仅内部IP访问 if (req.url == "/internal/sync-ban" && req.client.ip ~ "192.168.1.0/24") { ban("req.http.host == " + req.http.X-Sync-Host + " && req.url == " + req.http.X-Sync-Url); std.syslog(180, "[sync] - Executed ban for: " + req.http.X-Sync-Host + req.http.X-Sync-Url); return (synth(200, "Ban synced")); } }
- 修改原有的PUT/POST处理逻辑
在执行本地Ban后,调用std.httpcall触发远程节点的Ban:
sub vcl_recv { # 其他原有规则... if (req.url ~ "^/app/api/client($|/.*)" && (req.method == "POST" || req.method == "PUT")) { # 本地节点执行Ban ban("req.http.host == " + req.http.host + " && req.url == " + req.url); # 触发远程节点Ban(多节点可复制此段) std.httpcall( "192.168.1.102", 80, # 远程Varnish的IP和HTTP端口 "/internal/sync-ban", {"Host: " + req.http.host, "X-Sync-Host: " + req.http.host, "X-Sync-Url: " + req.url}, "", resp); std.syslog(180, "[debug][" + req.method + "] - Syncing cache purge for: " + req.http.host + req.url); return (pass); set req.backend_hint = web_node.backend(); } }
该方案无需额外脚本依赖,但要确保节点间HTTP端口互通,且内部IP限制严格,避免被外部恶意调用。
注意事项
- 免费版Varnish无内置集群同步,所有方案均依赖外部触发逻辑
- 若后续扩展更多节点,只需在脚本或
std.httpcall中新增对应节点的操作即可 - 建议测试Ban逻辑,确保缓存失效符合预期
内容的提问来源于stack exchange,提问作者Vladoul
相关产品推荐
相关产品推荐

