我正在努力解决一个后端服务器,该服务器将不时开始提供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 otherwise,vcl_deliver
似乎都不可写。这是在Varnish 3.0.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 :(得分:0)
在vcl_deliver中执行此操作为时已晚。在将内容发送到客户端之前调用此子,并且obj不再可用(仅'resp'不包含任何ttl或grace参数)。
您是否尝试在vcl_fetch中执行此操作?您不需要调用'restart'而是直接调用'hit_for_pass'。
无论如何,(不确定)我不认为可以使用宽限模式取决于响应内容,因为当你无法获得任何内容更新(后端失败)时它应该被触发。也许它可以通过将后端更改为“僵尸”并重新启动请求来工作但是当然,一旦你进入vcl_fetch,就会获取响应,并且不会触发宽限模式。