清漆4宽限时间取决于后端运行状况

时间:2015-10-06 15:28:34

标签: varnish-vcl varnish-4

我对在清漆4中设置宽限时间的位置感到困惑。我已经看到示例VCL在 vcl_recv 中设置宽限时间

sub vcl_recv {
    ...
    set req.http.grace = 60m;
    ...
}

其他人将其设置为 vcl_hit

sub vcl_hit {
    ...
    set obj.grace = 60m;
    ...
}

并在文档(https://www.varnish-cache.org/docs/4.0/users-guide/vcl-grace.html)中设置 vcl_backend_response

sub vcl_backend_response {
    ...
    set beresp.grace = 60m;
    ...
}

我也看到了在 vcl_recv vcl_backend_response 中设置宽限时间的示例。

有人可以解释为什么人们想把它放在一个特定的地方吗?

在实践中,我想根据后端是否健康来设置宽限时间;直觉上我在> varnish与后端联系之前设置了,所以我在 vcl_recv 中设置了宽限时间,并决定是否从 vcl_hit中的缓存服务喜欢这样:

sub vcl_recv {
    ...
    if (std.healthy(req.backend_hint)) {
        set req.http.grace = 2m;
    } else {
        set req.http.grace = 60m;
    }
    ...
}

sub vcl_hit {
    if (obj.ttl >= 0s) {
        # A standard hit, deliver from cache
        return (deliver);
    }
    elsif (obj.ttl + obj.grace > 0s) {
        # page expired, serve from cache in the meantime
        return (deliver);
    } else {
        return (fetch);
    }
}

这是正确的方法吗?

1 个答案:

答案 0 :(得分:4)

这是我研究的结果:

  1. vcl_recv 中设置 req.http.grace 并没有帮助,因为这只是定义了一个新的标题条目,否则varnish会忽略它
  2. vcl_hit 中设置 obj.grace 并不起作用,因为obj仅在清漆4中阅读
  3. 唯一可以设置宽限时间的地方,以便清漆识别它位于 beresp.grace
  4. 中的子程序 vcl_backend_response
  5. 因为宽限时间只能在 vcl_backend_response 中设置,根据后端的健康状况设置不同的宽限时间,因为只有当varnish在缓存未命中后从后端获取数据时才会调用此函数,这对我想要的已经太晚了。我需要在联系后端之前设置宽限时间。
  6. 我根据后端运行状况设置不同宽限期的解决方案是:

    1. 我将宽限时间设置为2个宽限时间的最大值:"正常的宽限时间"和#34;后端生病时的宽限期"
    2. 是否从缓存提供服务或联系后端是在 vcl_hit 中决定的;我能模仿第二个宽限时间的地方
    3. 以下是 vcl_hit 的外观

      sub vcl_hit {
              if (obj.ttl >= 0s) {
                      # A standard hit, deliver from cache
                      return (deliver);
              }
              elsif (std.healthy(req.backend_hint)) {
                      if (obj.ttl + 30m > 0s) {
                              # page expired within a limited grace time and backend
                              # is healthy: deliver from cache while cache is updated
                              # asynchronous
                              return (deliver);
                      } else {
                              # page expired too long ago - fetch from backend
                              return (fetch);
                      }
              }
              else {
                      if (obj.ttl + obj.grace > 0s) {
                              # backend is not healthy - provide the page from cache
                              # during full grace time set in vcl_backend_response
                              return (deliver);
                      } else {
                              # page expired for the full grace time and backend is
                              # considered unhealthy - try to contact the backend
                              # anyway
                              return (fetch);
                      }
              }
      }
      

      我在这里定义了#34;使用条件

      的第二个宽限时间为30分钟
                  if (obj.ttl + 30m > 0s) {
      

      vcl_backend_response 中,我只设置了6小时的最长宽限时间:

      sub vcl_backend_response {
              # define full grace time here
              set beresp.grace = 6h;
              ...
      }