我已经问过并收到一个很棒的答案,关于如何从后端获取错误以强制从此处找到的陈旧缓存(宽限期)提供服务:varnish 4: serve graced object if beresp.status is an error?
但是现在逻辑需要一个额外的步骤:我当前包含以下代码
sub vcl_backend_fetch {
if (bereq.retries == 0) {
unset bereq.http.X-Varnish-Backend-5xx;
unset bereq.http.X-Varnish-Backend-206;
} else {
if (bereq.http.X-Varnish-Backend-5xx) {
return (abandon);
}
if (bereq.http.X-Varnish-Backend-206) {
return (abandon);
}
}
}
sub vcl_synth {
if (resp.status == 503 &&
req.method != "POST" &&
!req.http.X-Varnish-Restarted-5xx) {
set req.http.X-Varnish-Restarted-5xx = "1";
return (restart);
}
if (resp.status == 503 &&
req.method != "POST" &&
!req.http.X-Varnish-Restarted-206) {
set req.http.X-Varnish-Restarted-206 = "1";
return (restart);
}
}
显然,vcl_synth中的第二个if语句实际上与第一个相同,但它正在查找的标题除外。我需要区分206以使用不同的请求标头重新启动,但我不确定如何。问题是,如果后端返回206,则逻辑的其余部分放弃后端获取(使用503移交给vcl_synth),并且vcl_synth重新启动强制提供服务增加的缓存对象的请求。但是,如果没有抓取缓存对象返回给用户,则用户会看到503而不是206.
在意识到这种思路不可能之前,我试图让vcl_backend_fetch返回一个合成器(206),这样vcl_synth就可以使用resp.status来区分,并在重新启动请求之前添加一个不同的请求头。那么我将能够在vcl_miss中查找该标题,如果它在那里,我可以再次重启整个请求,并强制它从通常的后端服务206。
TL; DR:如何在vcl_backend_fetch放弃中区分两种不同的情况,让vcl_synth用两个不同的标头重新启动请求?
答案 0 :(得分:0)
我很确定在vcl_backend_fetch
中执行任何操作都无法放弃请求并将某种标记转移到vcl_synth
。
我不确定我是否完全了解您的用例,但似乎需要这样的内容:
sub vcl_synth {
if (resp.status == 503 &&
req.method != "POST" &&
!req.http.X-Varnish-Restarted-5xx) {
# Let's restart the request for the first time and try to
# serve grace content. This could select an always-sick
# backend during vcl_recv.
set req.http.X-Varnish-Restarted-5xx = "1";
return (restart);
}
if (resp.status == 503 &&
req.method != "POST" &&
req.http.X-Varnish-Restarted-5xx &&
!req.http.X-Varnish-Restarted-206) {
# Grace content was not available after the first restart. Let's
# restart again the request and try to serve content using some
# other backend.
set req.http.X-Varnish-Restarted-206 = "1";
return (restart);
}
}