试图破译这个清漆vcl块(与恩典有关)

时间:2015-02-18 21:08:46

标签: varnish varnish-vcl

所以在我的vcl_recv中我设置了这个标题

set req.http.Grace = "NONE";

当后端启动时,所有内容都设置了Grace:NONE标头,这很好......然后我们有了

sub vcl_hit {

    # Called when a cache lookup is successful.
      if (obj.ttl >= 0s) {
        # A pure unadultered hit, deliver it
        return (deliver);
      }

     if (std.healthy(req.backend_hint)) {
        # Backend is healthy. Limit age to 10s.
            if (obj.ttl + 10s > 0s) {
                set req.http.Grace = "normal(limited)";
                return (deliver);
                            } else {
                            # No candidate for grace. Fetch a fresh object.
                            return(fetch);
                            }
      } else {
        # backend is sick - use full grace
            if (obj.ttl + obj.grace > 0s) {
                set req.http.Grace = "full";
                            return (deliver);
                            } else {
                            # no graced object.
                            return (fetch);
        }
      }

      # fetch & deliver once we get the result
      return (fetch); # Dead code, keep as a safeguard

    }

所以,我明白,显然完全优雅的是当后端关闭时,我知道如果后端没有下降,我们就不会调整优雅,但是当正常时(正常)阻止踢?似乎当后端启动时它会为Grace提供所有内容:NONE,如果我停止nginx,它会直接进入Grace:FULL。我不知道什么时候

    if (obj.ttl + 10s > 0s) {
        set req.http.Grace = "normal(limited)";

应该开始,因为我似乎无法做到,至少根据设置的标题......

我的vcl_backend_response有这些值(用于测试,但是是的)

# A TTL of 24h
set beresp.ttl = 60s;
# Define the default grace period to serve cached content
set beresp.grace = 6h;

1 个答案:

答案 0 :(得分:1)

有问题的块将在到期后的10秒内为第一个过期对象请求启动。

例如,您在00:00:00请求一个对象,它从后端获取并以60秒的TTL存储。如果您在00:01:07请求相同的对象,则应该收到(现已过期的)缓存对象并查看“正常(有限)”标题。

假设此VCL在Varnish 4.x上运行,则在宽限期内命中过期对象应触发后台刷新,因此任何子请求请求都应接收新缓存的对象。

简而言之,这条规则是:

  1. 将所有物品存放6小时1分钟
  2. 从缓存中提供小于60秒的对象
  3. 从缓存中提供60到70秒之间的对象,但在后台刷新缓存的对象
  4. 如果后端healhcheck失败,则仅从缓存中提供超过70秒的对象

  5. 更新:

    你几乎得到了它。存储对象 - 保存在内存中 - 用于TTL和宽限的总和。这就是我们如何达到最长6小时1分钟 - 6小时宽限和1分钟TTL的存储时间。

    TTL是您认为对象“新鲜”的时间长度,这意味着它可以从缓存中提供,而不检查它是否在原始服务器上发生了更改。另一方面,当一个物体不再“新鲜”时,格雷斯会开始玩,但无论如何你想要服务它 - 通常是出于以下两个原因之一:

    1. 您的后端失败,并且提供“陈旧”的过期对象比提供错误更好。
    2. 例如,考虑一个显示文章和评论的CMS。通常情况下,您希望保持TTL短,以便及时显示新评论。但是,如果您的CMS崩溃,您宁愿使用旧评论而不是“糟糕,服务器已死”页面来提供文章。

      1. 该对象最近到期,因此提供过期对象并不是一件大事 - 而且最好立即提供稍微过时的对象,而不是等待后端应用程序返回响应。
      2. 在这种情况下,请考虑聚合第三方供稿的应用程序 - 您宁愿提供稍微状态的供稿数据集,然后在后台刷新缓存的对象,而不是让用户等到所有调用完成第三方应用程序并汇总数据。