Grace模式和Keep¶
有时,您希望Varnish提供有些过时的内容,而不是等待来自后端的新对象。例如,如果您运行一个新闻站点,为几秒钟前的主页提供服务不是问题,如果这会使您的站点的加载速度更快。
在Varnish中,这是通过使用 grace mode 。一个相关的想法是 keep ,这里也解释了这一点。
Grace模式¶
当多个客户端请求相同的页面时,Varnish将向后端发送一个请求,并在从后端获取一个副本的同时搁置其他请求。在某些产品中,这称为请求合并,而Varnish会自动执行此操作。
如果您每秒处理数千次点击,等待请求的队列可能会变得很大。有两个潜在的问题--一个是雷鸣般的群组问题--突然释放一千个线程来提供内容可能会使负载达到极高的水平。其次,没有人喜欢等待。
设置对象的 grace 设置为正值告诉Varnish在TTL过期后应在一段时间内为客户端提供对象,而Varnish则获取对象的新版本。缺省值由运行时参数控制 default_grace
。
留着¶
设置对象的 keep 告诉Varnish它应该将对象在缓存中保留一段时间。设置的原因 keep 是使用对象构造一个有条件的GET后端请求(带有if-Modified-Since:和/或f-None-Match:头),允许后端使用304 Not Modify响应进行回复,这在后端可能会更高效,并省去了重新传输未更改的正文。
这些值是相加的,因此如果GREASE为10秒,KEEP为1分钟,则对象将在TTL过期后在缓存中存活70秒。
设置GREE和KEEP¶
我们可以使用VCL使Varnish将所有对象保留超过其TTL 10分钟,并有2分钟的宽限期::
sub vcl_backend_response {
set beresp.grace = 2m;
set beresp.keep = 8m;
}
恩典与守约的效果¶
对于大多数用户来说,为每个对象设置默认宽限和/或合适的宽限就足够了。默认的VCL将执行正确的操作,并按照上述方式运行。但是,如果您想要自定义Varnish的行为方式,那么您应该了解有关其工作方式的一些细节。
什么时候 sub vcl_recv
结尾为 return (lookup)
(这是默认行为),则Varnish将在其缓存中查找匹配的对象。然后,如果它只找到TTL已用完的对象,Varnish将考虑以下事项:
是否已有针对该对象的持续后端请求?
是位于 grace period ?
然后,Varnish使用以下规则进行反应:
如果 grace period 已经用完,并且没有正在进行的后端请求,则
sub vcl_miss
立即调用,则该对象将用作304候选对象。如果 grace period 已经用完,并且有一个正在进行的后端请求,则该请求将等待,直到后端请求完成。
如果没有针对该对象的后端请求,则会安排一个请求。
假设该对象将被递送,
sub vcl_hit
立即被呼叫。
请注意,后端提取是异步进行的,新对象在其中的那一刻将替换我们已经获得的对象。
如果你没有定义你自己的 sub vcl_hit
,则使用默认设置。它看起来像这样::
sub vcl_hit {
return (deliver);
}
请注意,该条件 obj.ttl + obj.grace > 0s
将(在 sub vcl_hit
)始终求值为真。在较早的版本(6.0.0和更早)中,情况并非如此,需要在内置VCL中进行测试,以确保不会将“保留对象”(缓存中TTL和宽限都已用完的对象)传递给客户端。
在当前版本中,当只有“保留对象”可用时, sub vcl_miss
将被调用,并且将启动对新对象的获取。
行为不端的服务器¶
Varnish的一个关键功能是它能够保护您免受Web和应用程序服务器行为不当的影响。
如果您已启用 健康检查 您可以检查后端是否有问题,并在遇到问题时修改行为。这可以通过以下方式完成:
sub vcl_backend_response {
set beresp.grace = 24h;
// no keep - the grace should be enough for 304 candidates
}
sub vcl_recv {
if (std.healthy(req.backend_hint)) {
// change the behavior for healthy backends: Cap grace to 10s
set req.grace = 10s;
}
}
在上面的示例中,特殊变量 req.grace
已经设置好了。其效果是,当后端运行状况良好时,宽限大于10秒的对象将具有 effective 10秒的恩典。当后端出现问题时,默认的VCL会生效,并使用长宽限期。
此外,当后端FETCH返回 5xx
错误::
sub vcl_backend_response {
if (beresp.status >= 500 && bereq.is_bgfetch) {
return (abandon);
}
}
摘要¶
Grace模式允许Varnish向客户提供略有陈旧的内容,同时从后端获得新版本。其结果是以更低的成本获得更快的加载时间。
可以通过设置来限制查找期间的宽限 req.grace
然后,当涉及到优雅时,改变行为。这样做通常是为了更改 effective Grace取决于后端的运行状况。