当长度为零时,如何使Varnish缓存中的对象无效?

时间:2012-03-06 13:45:26

标签: varnish varnish-vcl

我正在努力解决一个后端服务器,该服务器将不时开始提供200 OK响应的空白页面,让Varnish继续提供这些页面的旧缓存版本(也称为宽限模式)。

首先,我尝试检查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.ttl行,obj.grace会出现同样的错误 - 即使the docs say otherwisevcl_deliver似乎都不可写。这是在Varnish 3.0.2上。

2 个答案:

答案 0 :(得分:2)

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

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中抛出错误,如:错误751 req.http.host;
  2. 在vcl_error中添加魔术标记。
  3. 添加return(重启);在vcl_error
  4. 检查vcl_recv或vcl_fetch
  5. 中设置的魔术标记

答案 1 :(得分:0)

在vcl_deliver中执行此操作为时已晚。在将内容发送到客户端之前调用此子,并且obj不再可用(仅'resp'不包含任何ttl或grace参数)。

您是否尝试在vcl_fetch中执行此操作?您不需要调用'restart'而是直接调用'hit_for_pass'。

无论如何,(不确定)我不认为可以使用宽限模式取决于响应内容,因为当你无法获得任何内容更新(后端失败)时它应该被触发。也许它可以通过将后端更改为“僵尸”并重新启动请求来工作但是当然,一旦你进入vcl_fetch,就会获取响应,并且不会触发宽限模式。