内置VCL

每当加载VCL程序时,内置的VCL都会被附加到它的后面。VCL内置潜水器 (VCL步骤 )具有特殊属性,则它们可以多次出现,并且结果是所有内置子例程的串联。

例如,让我们使用以下代码片段::

sub vcl_recv {
    # loaded code for vcl_recv
}

提供给编译器的有效VCL如下所示:

sub vcl_recv {
    # loaded code for vcl_recv
    # built-in code for vcl_recv
}

这就是如何保证所有的 Varnish加工状态 至少有一个 return (<action>)

通常建议不要总是从加载的代码返回以让Varnish执行内置代码,因为内置代码基本上为HTTP缓存提供了合理的默认行为。

内置子例程拆分

但是,内置的VCL规则在状态结束时生效可能并不总是可行的,因此一些子例程,如 vcl_recv 被分成对其他子例程的多个调用。

按照惯例,这些辅助子例程以它们操作的变量命名,如 reqberesp 。例如,这允许绕过默认行为。

例如, vcl_recv 在内置的VCL中,当客户端有Cookie时,会阻止缓存。如果您可以信任您的后端始终指定响应是否可缓存,而不管请求是否包含Cookie,则可以执行以下操作:

sub vcl_req_cookie {
    return;
}

这样,来自内置的所有其他默认行为 vcl_recv 被执行,并且只影响Cookie处理。

另一个例子是内置的 vcl_backend_response 将负TTL视为不缓存的信号。这是一种将响应标记为不可缓存的历史机制,但只有在内置 vcl_backend_response 不会被一个 return (<action>)

然而,在后端可能是另一个Varnish服务器的多层体系结构中,您可能希望缓存陈旧的响应,以允许传递优雅的对象,并在下一次获取时启用重新验证。这可以使用以下代码片段来完成:

sub vcl_beresp_stale {
    if (beresp.ttl + beresp.grace > 0s) {
        return;
    }
}

这种粒度和内置子例程拆分的一般目标是允许在不放弃整个逻辑的情况下绕过默认规则的特定方面。

内置VCL参考

一份 builtin.vcl 文件可能随Varnish安装一起提供,但是 华而不实 是用于确定附加到任何加载的VCL的代码的引用。

VCL编译分两次进行:

  • 第一个只编译内置的VCL,

  • 第二遍编译加载的和内置的VCL的级联。

内置VCL中存在的任何VCL子例程都可以扩展,在这种情况下,加载的VCL代码将在内置代码之前执行。