问题描述
考虑我请求的 url 是 www.example.com/foo/emplooyee?names = test1;test2。 varnish 将整个 URL 与查询参数一起存储以唯一标识缓存。
现在,在我的后端,我正在运行一项服务,我应该将其配置为每当名称(即 test1 或 test2)发生变化时,应该使用一个较旧的名称(在禁止表达式中一次使用一个名称)以使所有以相似名称输入的缓存 URL 无效。
问题: 我的客户端请求 url 可能是这样的,
- www.example.com/foo/emplooyee?names = test1;test2
- www.example.com/foo/emplooyee?names = test1;
- www.example.com/foo/emplooyee?names = test2;test1;test3;test4
- www.example.com/foo/emplooyee?names = test1;test4.
如何编写 VCL 代码并在 Ban 表达式中使查询参数为 test1 的所有对象无效?
解决方法
这是您禁止所需的 VCL 代码:
vcl 4.1;
acl purge {
"localhost";
"192.168.55.0"/24;
}
sub vcl_recv {
if (req.method == "PURGE") {
if (!client.ip ~ purge) {
return(synth(405));
}
if(!req.http.x-invalidate-pattern) {
return(purge);
}
ban("obj.http.x-url ~ " + req.http.x-invalidate-pattern
+ " && obj.http.x-host == " + req.http.host);
return (synth(200,"Ban added"));
}
}
sub vcl_backend_response {
set beresp.http.x-url = bereq.url;
set beresp.http.x-host = bereq.http.host;
}
sub vcl_deliver {
unset resp.http.x-url;
unset resp.http.x-host;
}
以下是使查询字符串中包含 test1
值的所有请求无效的 HTTP 请求示例:
PURGE / HTTP/1.1
Host: www.example.com
X-Invalidate-Pattern: ^/foo/emplooyee\?names=([^;]+;)*test1(;[^;]+)*$
这是通过 curl
发出的相同请求:
curl -XPURGE -H'X-Invalidate-Pattern: ^/foo/emplooyee\?names=([^;]+;)*test1(;[^;]+)*$' http://www.example.com
这个 VCL 片段可以灵活地通过禁止从缓存中删除多个项目,但如果您不通过 X-Invalidate-Pattern
标头设置模式,它只会从缓存中删除 URL 本身。
以下是我们仅从缓存中删除 http://www.example.com/foo/emplooyee?names=test1
的示例:
curl -XPURGE 'http://www.example.com/foo/emplooyee?names=test1'
不要忘记修改 VCL 代码中的 acl
块并添加正确的 IP 地址或 IP 范围。