VCL return(查找)

VCL return(lookup)

我们正在使用 Fastly 及其 Varnish 从我们的服务中交付内容。为了在多个服务之间分发内容,我们使用以下代码段:

    sub vcl_recv {
      #FASTLY recv
      if (req.url.path ~ "^/services/") {
        set req.url = regsub(req.url, "/services/(.*?)/", "/");
      }
    }

这有效并允许我们将 /services/user/get 传送到 user 服务的 /get 端点。

然而,使用此代码段会使 Fastly 完全跳过 gzip 压缩。这可以通过使用 return(lookup):

来解决
    sub vcl_recv {
      #FASTLY recv
      if (req.url.path ~ "^/services/") {
        set req.url = regsub(req.url, "/services/(.*?)/", "/");
      }
      return (lookup);
    }

此时 gzip 压缩开始工作。不幸的是,这使得所有 POSTPATCHDELETE 请求都以 GET.

的形式到达

我试图研究 Varnish 文档,但我不确定 (lookup) 是否真的是我需要的领域。你能告诉我应该如何实施吗?

内置 VCL

Varnish 使用内置的 VCL 来创建一组通用规则。它们充当最终用户的安全网。

有关内置 VCL,请参阅 https://github.com/varnishcache/varnish-cache/blob/master/bin/varnishd/builtin.vcl

此代码和此文件不应由您加载,但当您未在其中一个子例程中执行显式 return 语句时会自动执行。

任何显式 return 语句都会绕过默认行为。有时这需要自定义 Varnish 的行为。但有时它会适得其反并导致不良行为。

return(lookup) 声明的后果

负责处理传入请求的sub vcl_recv {}子例程执行无条件return(lookup)

这意味着每个请求都会导致缓存查找,即使内置 VCL 更愿意将这些请求直接传递到后端。

有两种决定缓存的策略:

  • 定义可以缓存的规则并对所有其他请求执行return(pass)
  • 定义无法缓存的规则并对所有其他请求执行 return(lookup)

基本上是 blacklist/whitelist 那种东西。

GET & HEAD 与其他请求方法

内置VCL只允许缓存GETHEAD请求。其他请求方法,例如 POST,意味着将发生统计变化。这就是它们没有被缓存的原因。

如果您尝试为 POST 调用执行 return(lookup),Varnish 将在内部将此请求更改为 GET

有一些方法可以缓存 POST 调用,但通常您不应该这样做。

你应该如何构建你的 sub vcl_recv {}

我建议您从 sub vcl_recv {} 子例程中删除 return(lookup) 语句。

如前所述,一旦您退出自定义 sub vcl_recv {},内置 VCL 就会接管工作 sub vcl_recv {}

但是,内置的 VCL 不会有太大帮助,因为您的网站可能有一些 cookie。

以明智的方式剥离 cookie 并为需要 cookie 的请求保留它们很重要。对于这些页面,将插入 return(pass) 以确保这些个性化请求不会在缓存中查找,而是直接传递到后端。

gzip 怎么样?

可以找出 gzip 停止工作的原因。 varnishlog 工具允许您检查 运行 系统并过滤掉日志。

请参阅 https://feryn.eu/blog/varnishlog-measure-varnish-cache-performance/ 以获得广泛的博客 post 我写了关于这个主题的文章。

也许 varnishlog 可以帮助您找到 gzip 压缩有时停止工作的原因。