我正在使用Varnish cache 6.0.6。有时候,我需要根据URL忽略GET参数和任何头文件而使缓存无效。我使用 BAN
命令来实现。
GET命令来检索内容。它们收到的结果是不同的。
curl --user login:secret 'http://example.com/v1/account/123'
curl --user login2:secret2 'http://example.com/v1/account/123?origin=abc'
BAN命令来禁止两个缓存。
curl -X BAN example.com -H "X-Ban: /v1/account/123"
Varnish配置
if (req.method == "BAN") {
if (!client.ip ~ purge) {
return (synth(405, "Not allowed"));
}
ban("obj.http.x-host == " + req.http.host + " && obj.http.x-url ~ " + req.http.X-Ban);
return (synth(200, "Ban added"));
}
但是ban命令只对第一个请求的缓存无效,第二个请求会保留缓存。如何才能使所有以 ^/v1/account/123
?
我已经在本地设置上进行了测试,它似乎不需要任何改变就可以工作。
这是最初的请求,你可以看到: Age: 35
意味着该项目已在缓存中存储了35秒。
➜ ~ curl -I localhost/v1/account/123\?origin=abc
HTTP/1.1 200 OK
Content-Type: text/plain
Date: Fri, 15 May 2020 07:26:59 GMT
Content-Length: 216
x-host: localhost
x-url: /v1/account/123?origin=abc
X-Varnish: 32788 32786
Age: 35
Via: 1.1 varnish (Varnish/6.0)
Accept-Ranges: bytes
Connection: keep-alive
下一个请求会发出禁令,使用你在VCL中描述的精确语法。
➜ ~ curl -X BAN localhost -H "X-Ban: /v1/account/123"
<!DOCTYPE html>
<html>
<head>
<title>200 Ban added</title>
</head>
<body>
<h1>Error 200 Ban added</h1>
<p>Ban added</p>
<h3>Guru Meditation:</h3>
<p>XID: 14</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
当我再次执行最初的 curl 调用时,会发现 Age
头被重置为零,这意味着页面没有从缓存中提供服务。这是我们所期望的结果。
➜ ~ curl -I localhost/v1/account/123\?origin=abc
HTTP/1.1 200 OK
Content-Type: text/plain
Date: Fri, 15 May 2020 07:40:23 GMT
Content-Length: 213
x-host: localhost
x-url: /v1/account/123?origin=abc
X-Varnish: 16
Age: 0
Via: 1.1 varnish (Varnish/6.0)
Accept-Ranges: bytes
Connection: keep-alive
这是本例中使用的完整VCL,请根据需要调整后台& ACL设置。请根据您的需要调整后台& ACL设置。
请确保 x-host
& x-url
适当设置在 sub vcl_backend_response
否则,你的禁令声明将无法匹配这些值。这就是我们所说的 方便潜伏者的禁令.
vcl 4.0;
backend default {
.host="localhost";
.port="8080";
}
acl purge {
"localhost";
}
sub vcl_recv {
if (req.method == "BAN") {
if (!client.ip ~ purge) {
return (synth(405, "Not allowed"));
}
ban("obj.http.x-host == " + req.http.host + " && obj.http.x-url ~ " + req.http.X-Ban);
return (synth(200, "Ban added"));
}
}
sub vcl_backend_response {
set beresp.http.x-host = bereq.http.host;
set beresp.http.x-url = bereq.url;
}