【问题标题】:How do I invalidate an object in the Varnish cache when it has zero length?当 Varnish 缓存中的对象长度为零时,如何使其无效?
【发布时间】:2012-03-24 00:03:43
【问题描述】:

我正在尝试通过让 Varnish 继续提供这些页面的旧缓存版本(又名宽限模式)来解决后端服务器的问题,该服务器将不时开始提供具有 200 OK 响应的空白页面。

首先我尝试检查vcl_fetch 中的响应,但据我所知,无法确定vcl_fetch 中的内容长度。然后我尝试在vcl_deliver 中完成这项工作(Content-Length 标头可用)。这确实有效,但我不知道如何删除坏缓存对象(带有空白页的对象),所以这似乎是不行的。

有人建议我在vcl_deliver 中设置 obj.grace 和 obj.ttl,这是我当前的代码:

sub vcl_deliver {
  # If the front page is blank, invalidate this cached object, in hope
  # that we'll get a new one.
  if (req.url == "/" && std.integer(resp.http.content-length, 0) < 1000) {
    set obj.grace = 0m;
    set obj.ttl = 0m;

    return(restart);
  }
}

但是,Varnish 不喜欢这样,并在我尝试加载 VCL 时给我这个错误:

Message from VCC-compiler:
'obj.grace': cannot be set in method 'vcl_deliver'.
At: ('input' Line 146 Pos 9)
    set obj.grace = 0m;
--------#########------

如果我删除 obj.grace 行,obj.ttl 会出现相同的错误 - 即使 the docs say otherwise 似乎也无法在 vcl_deliver 中写入。这是在 Varnish 3.0.2 上。

【问题讨论】:

    标签: varnish varnish-vcl


    【解决方案1】:

    在 vcl_deliver 中执行此操作为时已晚。这个 sub 在向客户端发送内容之前被调用,并且 obj 不再可用(只有 'resp' 不包含任何 ttl 或 Grace 参数)。

    您是否尝试在 vcl_fetch 中执行此操作?您无需调用“restart”,而是直接调用“hit_for_pass”。

    无论如何,(不确定)我不认为可以根据响应内容使用宽限模式,因为它应该在您无法获得任何内容更新(后端故障)时触发。也许它可以通过将后端更改为“僵尸”并重新启动请求来工作,但可以肯定的是,一旦你在 vcl_fetch 中,就会......获取响应,并且不会触发宽限模式。

    【讨论】:

    • 问题是我无法弄清楚我们是否在vcl_fetch 中得到了一个空响应。
    • 你可以。只需检查“beresp.http.content-length”而不是“resp”,这样您就可以检查从后端接收到的内容,而不是将发送到客户端的内容。
    • 我认为您的建议类似于: if(!beresp.http.content-length) { set obj.grace = 5m; } 但这对我来说仍然失败。
    • if(!beresp.http.content-length) 检查标头是否存在,而不是其值。你应该使用if(beresp.http.content-length != "0")(你不能使用&gt; 0,因为标头是作为字符串提供的)。
    【解决方案2】:

    我所做的是检查 sub_vcl_fech 中 0 和 20 的 Content-Length 并在发生这种情况时重新启动

    if (beresp.http.Content-Length == "0" || beresp.http.Content-Length == "20"){
        return(restart);
    }
    

    发生错误时我的服务器返回的内容长度为 20。

    在子 vcl_recv 中,我添加了对最多 2 次重启次数的检查

    if(req.restarts == 2){
       error 500 req.http.host;
    }
    

    选项 2

    我从清漆文档中获得的另一个选项。 https://www.varnish-cache.org/docs/3.0/tutorial/handling_misbehaving_servers.html

    1. 在 vcl_fetch 中抛出错误,例如:error 751 req.http.host;
    2. 在 vcl_error 中添加魔术标记。
    3. 添加返回(重启);在 vcl_error 中
    4. 检查在 vcl_recv 或 vcl_fetch 中设置的魔术标记

    【讨论】:

      猜你喜欢
      • 2017-07-24
      • 1970-01-01
      • 2011-05-26
      • 1970-01-01
      • 2021-09-03
      • 1970-01-01
      • 2019-06-05
      • 2011-01-20
      • 2012-04-27
      相关资源
      最近更新 更多