如何使用 Ban 表达式使清漆缓存对象无效

问题描述

考虑我请求的 url 是 www.example.com/foo/emplooyee?names = test1;test2。 varnish 将整个 URL 与查询参数一起存储以唯一标识缓存。

现在,在我的后端,我正在运行一项服务,我应该将其配置为每当名称(即 test1 或 test2)发生变化时,应该使用一个较旧的名称(在禁止表达式中一次使用一个名称)以使所有以相似名称输入的缓存 URL 无效。

问题: 我的客户端请求 url 可能是这样的,

如何编写 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 范围。