清漆 - stale-while-revalidate 似乎没有重新验证
Varnish - stale-while-revalidate doesn't appear to revalidate
我们正在使用 Varnish 缓存 6.2 位于我们的 WebAPI 后端之前。
后端正在针对某些请求返回 cache-control header,对于我们可以缓存更长时间的内容。
但是 - 如果后端宕机,并且一直宕机,我们会发送 stale-while-revalidate 一个小时。
因此来自我们后端的典型 cache-control 响应 header 看起来像:
public, max-age=30, stale-while-revalidate=3600
在我们的 Varnish VCL 中,我们添加了一个例程,用于在某些错误时停止后台获取。这是为了阻止后端的不良响应进入缓存:
sub vcl_backend_response {
if (beresp.status == 500 || beresp.status == 502 || beresp.status == 503 || beresp.status == 504)
{
if (bereq.is_bgfetch)
{
return (abandon);
}
set beresp.ttl = 1s;
}
}
我们面临的问题很简单 - Varnish 在 Max-Age 过期后不会更新缓存中的项目,即使后端可用。 (并且响应发生了变化)
我们已经看到来自 Varnish 的响应 "Age" header 超过 200 秒且响应错误的问题。我们还看到 "Age" header 为 1-3 秒的情况,这表明发生了后台提取(或正常提取)。
这种情况经常发生,我们注意到了 - 但并非每次请求都如此。
我试过简单的"pass",比如varnish中的如下:
sub vcl_recv {
return(pass);
}
然而,这似乎没有效果。
Varnish 设置是否还有其他可能导致上述情况的原因?
编辑,根据评论,这是我们添加到每个与我们的请求交互的子程序的小东西,以查看实际发生的情况:
sub vcl_deliver {
if (obj.uncacheable) {
set req.http.x-cache = req.http.x-cache + " uncacheable" ;
} else {
set req.http.x-cache = req.http.x-cache + " cached" ;
}
set resp.http.x-cache = req.http.x-cache;
}
sub vcl_hit {
set req.http.x-cache = "hit";
}
这是预期的行为。一旦第一次从后端获取对象(即 t=0
),Varnish 将其缓存设置为 beresp.ttl
到 30s
和 beresp.grace
到 3600s
。然后,如果你在 t=3000
时向 Varnish 请求对象,旧对象将被传递到客户端(即 Age: 3000
)并触发异步后台获取以刷新缓存对象。如果您在 t=3001
时再次向 Varnish 请求对象,如果后台提取已经完成其工作,则会传送一个新对象(即 Age: 1
)。以下测试说明了此行为:
varnishtest "..."
server s1 {
rxreq
txresp -hdr "Cache-Control: public, max-age=1, stale-while-revalidate=60" \
-hdr "Version: 1"
rxreq
txresp -hdr "Cache-Control: public, max-age=1, stale-while-revalidate=60" \
-hdr "Version: 2"
} -start
varnish v1 -vcl+backend {
} -start
client c1 {
txreq
rxresp
expect resp.http.Version == 1
expect resp.http.Age == 0
delay 5.0
txreq
rxresp
expect resp.http.Version == 1
expect resp.http.Age == 5
delay 0.1
txreq
rxresp
expect resp.http.Version == 2
expect resp.http.Age == 0
} -run
varnish v1 -expect client_req == 3
为了在缓存中的项目消耗其 TTL 后同步刷新对象,您需要在 vcl_recv
期间使用 req.grace
。如果后端健康,您可能希望将其设置为 0s
。请查看 https://varnish-cache.org/docs/trunk/users-guide/vcl-grace.html#misbehaving-servers 了解详情。
我们正在使用 Varnish 缓存 6.2 位于我们的 WebAPI 后端之前。 后端正在针对某些请求返回 cache-control header,对于我们可以缓存更长时间的内容。
但是 - 如果后端宕机,并且一直宕机,我们会发送 stale-while-revalidate 一个小时。
因此来自我们后端的典型 cache-control 响应 header 看起来像:
public, max-age=30, stale-while-revalidate=3600
在我们的 Varnish VCL 中,我们添加了一个例程,用于在某些错误时停止后台获取。这是为了阻止后端的不良响应进入缓存:
sub vcl_backend_response {
if (beresp.status == 500 || beresp.status == 502 || beresp.status == 503 || beresp.status == 504)
{
if (bereq.is_bgfetch)
{
return (abandon);
}
set beresp.ttl = 1s;
}
}
我们面临的问题很简单 - Varnish 在 Max-Age 过期后不会更新缓存中的项目,即使后端可用。 (并且响应发生了变化) 我们已经看到来自 Varnish 的响应 "Age" header 超过 200 秒且响应错误的问题。我们还看到 "Age" header 为 1-3 秒的情况,这表明发生了后台提取(或正常提取)。
这种情况经常发生,我们注意到了 - 但并非每次请求都如此。
我试过简单的"pass",比如varnish中的如下:
sub vcl_recv {
return(pass);
}
然而,这似乎没有效果。
Varnish 设置是否还有其他可能导致上述情况的原因?
编辑,根据评论,这是我们添加到每个与我们的请求交互的子程序的小东西,以查看实际发生的情况:
sub vcl_deliver {
if (obj.uncacheable) {
set req.http.x-cache = req.http.x-cache + " uncacheable" ;
} else {
set req.http.x-cache = req.http.x-cache + " cached" ;
}
set resp.http.x-cache = req.http.x-cache;
}
sub vcl_hit {
set req.http.x-cache = "hit";
}
这是预期的行为。一旦第一次从后端获取对象(即 t=0
),Varnish 将其缓存设置为 beresp.ttl
到 30s
和 beresp.grace
到 3600s
。然后,如果你在 t=3000
时向 Varnish 请求对象,旧对象将被传递到客户端(即 Age: 3000
)并触发异步后台获取以刷新缓存对象。如果您在 t=3001
时再次向 Varnish 请求对象,如果后台提取已经完成其工作,则会传送一个新对象(即 Age: 1
)。以下测试说明了此行为:
varnishtest "..."
server s1 {
rxreq
txresp -hdr "Cache-Control: public, max-age=1, stale-while-revalidate=60" \
-hdr "Version: 1"
rxreq
txresp -hdr "Cache-Control: public, max-age=1, stale-while-revalidate=60" \
-hdr "Version: 2"
} -start
varnish v1 -vcl+backend {
} -start
client c1 {
txreq
rxresp
expect resp.http.Version == 1
expect resp.http.Age == 0
delay 5.0
txreq
rxresp
expect resp.http.Version == 1
expect resp.http.Age == 5
delay 0.1
txreq
rxresp
expect resp.http.Version == 2
expect resp.http.Age == 0
} -run
varnish v1 -expect client_req == 3
为了在缓存中的项目消耗其 TTL 后同步刷新对象,您需要在 vcl_recv
期间使用 req.grace
。如果后端健康,您可能希望将其设置为 0s
。请查看 https://varnish-cache.org/docs/trunk/users-guide/vcl-grace.html#misbehaving-servers 了解详情。