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取决于后端的运行状况。