服务器容错 Misbehaving servers

Varnish的一个关键特色就是它有能力防御 web和应用服务器宕机

优雅模式 Grace mode

当几个客户端请求同一个页面的时候,varnish只发送一个请求到后端服务器,然后让那个其他几个请求挂起等待返回结果,返回结果后,复制请求的结果发送给客户端。在一些产品中,这个可能叫请求合并。varnish这些都是自动完成的。

如果您的服务每秒有数千万的点击率,那么这个队列是庞大的。这就有两个潜在的问题:一个是惊群问题——即突然释放大量线程去复制后端的结果,可能会导致负载急剧上升。第二个问题就是没有用户喜欢等待服务器响应。为了解决这个问题,我们可以让varnish保持对象在缓存中,让它不失效,这样就可以使用缓存中内容返回给客户端,而不用担心等待。

所以为了使用过期的 cache 给用户提供服务,我们需要增加他们的 TTL,保存所有cache 中的内容在 TTL过期以后依然可以保持2分钟:

sub vcl_backend_response {
  set beresp.grace = 2m;
}

现在Varnish允许在对象过期后2分钟内提供给客户端。同时varnish也将刷新这个对象。刷新动作是异步发生的,新的对象将替换老对象。

你可以在vcl_hit中添加代码来影响这种逻辑的运行,默认看起来是这样的:

sub vcl_hit {
   if (obj.ttl >= 0s) {
       // A pure unadultered hit, deliver it
       return (deliver);
   }
   if (obj.ttl + obj.grace > 0s) {
       // Object is in grace, deliver it
       // Automatically triggers a background fetch
       return (deliver);
   }
   // fetch & deliver once we get the result
   return (fetch);
}

grace逻辑在这里很明显。如果你开启了健康检查,你可以检查后端是否出了问题,然后直接宽限对象失效时间即可。用如下的if语句替换掉上面的第二个if语句块:

if (!std.healthy(req.backend_hint) && (obj.ttl + obj.grace > 0s)) {
      return (deliver);
} else {
      return (fetch);
}

综上所述,优雅模式解决了两个问题:

  • 提供旧内容给客户端以避免请求堆积。

  • 如果你允许varnish可以提供过期的内容。

results matching ""

    No results matching ""