首页 > 解决方案 > 跨 VCL 重新加载传递 Varnish 结构变量

问题描述

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

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

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

例如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";
    }
}

但是在这种情况下,编译失败是因为myobj未定义 in pub.vcl,这意味着它不携带 from master.vcl

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

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

谢谢。

标签: varnishvarnish-vcl

解决方案


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

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

或者,您可以使用该Event函数来使用PRIV_VCLhttps://stackoverflow.com/a/60753085)也引用全局指针并完全避免使用对象。例如,这是在这里完成的:https ://github.com/varnish/varnish-modules/blob/master/src/vmod_vsthrottle.c#L345


推荐阅读