Varnish 缓存由 vcl_backend_error 生成的响应
Varnish caches a response that has been generated by vcl_backend_error
我们运行 设置了 Varnish 将后端请求缓存到多个后端实例。这是使用 Director VMOD 处理的。当在后端服务器上完成新代码的新部署时,它们会离线几秒钟,也许一分钟,但这是交错部署,因此首先将代码部署到一个实例,然后再重新在线, 到下一个等等
当实例正在部署时,它将关闭其网络服务器,以确保在部署过程中没有处理任何请求。为了处理这个问题,Varnish VCL 内置了一个重启循环:
sub vcl_deliver {
# Restart specifically to catch timeouts on deploy
if (resp.status >= 500) {
# Restart goes to vcl_req and the director should choose another backend from the pool
return(restart);
}
强制重启将导致 Director VMOD 获取下一个未部署的实例(因为只有一个实例同时部署)并获得有效答案。这很好用。
但是,当后端提取导致 FetchError HTC status -1
(输入意外结束,由网络服务器关闭 midrequest 引起)时,将调用 vcl_backend_error 子例程。发生这种情况时,将按预期触发重启,但 Varnish 不会转到 vcl_backend_fetch,而是显然将生成的响应缓存在 VCL_backend_error 和 returns 中。原始响应和重新启动响应的相关部分下方:
VCL_call RECV
- VCL_return hash
- ReqUnset Accept-Encoding: gzip, deflate
- ReqHeader Accept-Encoding: gzip
- VCL_call HASH
- VCL_return lookup
- VCL_call MISS
- VCL_return fetch
- Link bereq 101974384 fetch
- Timestamp Fetch: 1545038546.336891 8.103600 8.103600
- RespProtocol HTTP/1.1
- RespStatus 503
- RespReason Backend fetch failed
- RespHeader Date: Mon, 17 Dec 2018 09:22:26 GMT
- RespHeader Server: Varnish
- RespHeader Content-Type: text/html; charset=utf-8
- RespHeader Retry-After: 5
- RespHeader X-Varnish: 101974383
- RespHeader Age: 0
- RespHeader Via: 1.1 varnish (Varnish/5.0)
- VCL_call DELIVER
- VCL_return restart
- Timestamp Process: 1545038546.336900 8.103608 0.000008
- Timestamp Restart: 1545038546.336902 8.103611 0.000003
- Link req 101974385 restart
- End
VCL_call RECV
- VCL_return hash
- VCL_call HASH
- VCL_return lookup
- Hit 101974384
- VCL_call HIT
- VCL_return deliver
- RespProtocol HTTP/1.1
- RespStatus 503
- RespReason Backend fetch failed
- RespHeader Date: Mon, 17 Dec 2018 09:22:26 GMT
- RespHeader Server: Varnish
- RespHeader Content-Type: text/html; charset=utf-8
- RespHeader Retry-After: 5
- RespHeader X-Varnish: 101974385 101974384
- RespHeader Age: 0
- RespHeader Via: 1.1 varnish (Varnish/5.0)
- VCL_call DELIVER
- VCL_return restart
- Timestamp Process: 1545038546.336929 8.103637 0.000027
- Timestamp Restart: 1545038546.336932 8.103640 0.000003
- Link req 101974386 restart
- End
然后它不断重新启动,从缓存中获取 503 错误,重新启动等,直到达到重新启动限制。
这种行为是故意的吗?有谁知道为什么会发生这种情况以及如何防止这种情况发生?
是的,这是预期的行为。来自文档:
A vcl_synth defined object is never stored in cache, contrary to a vcl_backend_error defined object, which may end up in cache. vcl_synth and vcl_backend_error replace vcl_error from Varnish 3.
像往常一样,您可以避免在 vcl_backend_error
期间简单地执行 set beresp.uncacheable = true;
。
我们运行 设置了 Varnish 将后端请求缓存到多个后端实例。这是使用 Director VMOD 处理的。当在后端服务器上完成新代码的新部署时,它们会离线几秒钟,也许一分钟,但这是交错部署,因此首先将代码部署到一个实例,然后再重新在线, 到下一个等等
当实例正在部署时,它将关闭其网络服务器,以确保在部署过程中没有处理任何请求。为了处理这个问题,Varnish VCL 内置了一个重启循环:
sub vcl_deliver {
# Restart specifically to catch timeouts on deploy
if (resp.status >= 500) {
# Restart goes to vcl_req and the director should choose another backend from the pool
return(restart);
}
强制重启将导致 Director VMOD 获取下一个未部署的实例(因为只有一个实例同时部署)并获得有效答案。这很好用。
但是,当后端提取导致 FetchError HTC status -1
(输入意外结束,由网络服务器关闭 midrequest 引起)时,将调用 vcl_backend_error 子例程。发生这种情况时,将按预期触发重启,但 Varnish 不会转到 vcl_backend_fetch,而是显然将生成的响应缓存在 VCL_backend_error 和 returns 中。原始响应和重新启动响应的相关部分下方:
VCL_call RECV
- VCL_return hash
- ReqUnset Accept-Encoding: gzip, deflate
- ReqHeader Accept-Encoding: gzip
- VCL_call HASH
- VCL_return lookup
- VCL_call MISS
- VCL_return fetch
- Link bereq 101974384 fetch
- Timestamp Fetch: 1545038546.336891 8.103600 8.103600
- RespProtocol HTTP/1.1
- RespStatus 503
- RespReason Backend fetch failed
- RespHeader Date: Mon, 17 Dec 2018 09:22:26 GMT
- RespHeader Server: Varnish
- RespHeader Content-Type: text/html; charset=utf-8
- RespHeader Retry-After: 5
- RespHeader X-Varnish: 101974383
- RespHeader Age: 0
- RespHeader Via: 1.1 varnish (Varnish/5.0)
- VCL_call DELIVER
- VCL_return restart
- Timestamp Process: 1545038546.336900 8.103608 0.000008
- Timestamp Restart: 1545038546.336902 8.103611 0.000003
- Link req 101974385 restart
- End
VCL_call RECV
- VCL_return hash
- VCL_call HASH
- VCL_return lookup
- Hit 101974384
- VCL_call HIT
- VCL_return deliver
- RespProtocol HTTP/1.1
- RespStatus 503
- RespReason Backend fetch failed
- RespHeader Date: Mon, 17 Dec 2018 09:22:26 GMT
- RespHeader Server: Varnish
- RespHeader Content-Type: text/html; charset=utf-8
- RespHeader Retry-After: 5
- RespHeader X-Varnish: 101974385 101974384
- RespHeader Age: 0
- RespHeader Via: 1.1 varnish (Varnish/5.0)
- VCL_call DELIVER
- VCL_return restart
- Timestamp Process: 1545038546.336929 8.103637 0.000027
- Timestamp Restart: 1545038546.336932 8.103640 0.000003
- Link req 101974386 restart
- End
然后它不断重新启动,从缓存中获取 503 错误,重新启动等,直到达到重新启动限制。
这种行为是故意的吗?有谁知道为什么会发生这种情况以及如何防止这种情况发生?
是的,这是预期的行为。来自文档:
A vcl_synth defined object is never stored in cache, contrary to a vcl_backend_error defined object, which may end up in cache. vcl_synth and vcl_backend_error replace vcl_error from Varnish 3.
像往常一样,您可以避免在 vcl_backend_error
期间简单地执行 set beresp.uncacheable = true;
。