跨 VCL 重新加载传递 Varnish 结构变量

Passing Varnish struct variables across VCL reloads

我构建了一个 Varnish VMOD,它定义了一个 object,它在 vcl_init 中实例化并始终保存在内存中,并在各个请求中使用。

我的配置分为几个 VCL 文件,这些文件根据一些请求参数从“主”VCL 加载。

主 VCL 还实例化了有问题的 object,我想在另一个 VCL 中使用它。我不在使用它的同一个 VCL 中实例化 object 的原因是我有另一个 VCL 定义了一些 ACL-restricted 路由来从数据源更新 object .

例如master.vcl:

sub vcl_init {
    new myobj = mymodule.myobject();
}

sub vcl_recv {
    if (req.url ~ "^pub/") {
        return (vcl (pub_vcl));
    }
    // Other switches...
}

pub.vcl:

sub vcl_recv {
    if myobj.mymethod() {
        set req.http.x-bogus = "true";
    }
}

但在这种情况下,编译失败,因为myobjpub.vcl中未定义,这意味着它不携带来自master.vcl

我还考虑过在加载 pub.vcl 之前在 master.vcl 中添加测试和 header 设置,但这不会起作用,因为加载 VCL 会调用 std.rollback(req)取消设置所有请求 headers,这是 vcl_recv.

中唯一可访问的变量

有没有办法在 VCL 重新加载时传递此状态?

谢谢。

您不能直接对对象执行此操作,因为它们在 VCL 范围内并且无法“转义”它。正如你所经历的,你需要先加载带标签的vcl,所以你还需要在其中创建对象。

但是没有什么能阻止您创建引用全局变量的对象,这样所有对象都可以访问相同的数据。

或者,您可以使用 Event 函数来使用 PRIV_VCL () also referencing a global pointer and avoid using objects completely. This is what is done here for example: https://github.com/varnish/varnish-modules/blob/master/src/vmod_vsthrottle.c#L345