强制请求错过caching但仍保存响应

我有一个缓慢的Web应用程序,我已经放在前面的清漆。 所有的页面都是静态的(对于不同的用户,它们不会有所不同),但是它们需要每5分钟更新一次,以便包含最新的数据。

我有一个简单的脚本( wget --mirror ),每隔15分钟就会抓取整个网站。 每次爬行大约需要5分钟。 抓取的重点是更新Varnishcaching中的每个页面,以便用户永远不必等待页面生成(因为所有页面最近都是由于蜘蛛而生成的)。

时间表如下所示:

  • 00:00:00:caching刷新
  • 00:00:00:蜘蛛开始爬行更新caching与新的页面
  • 00:05:00:蜘蛛完成爬行,所有页面更新,直到00:15:00

来自0:00:00和0:05:00之间的请求可能会触发尚未更新的页面,并且将被迫等待几秒钟以进行响应。 这是不可接受的。

我想要做的是,也许使用一些VCL魔术,总是从蜘蛛向后端发出请求,但仍然将响应存储在caching中。 这样,用户将永远不必等待页面生成,因为没有5分钟的窗口,其中caching的一部分是空的(除了在服务器启动时)。

我该怎么做?

req.hash_always_miss应该做的伎俩。

在蜘蛛运行开始时,不要执行完全caching刷新。 相反,只要设置蜘蛛工作 – 并在您的vcl_recv ,设置蜘蛛的请求总是错过caching查找; 他们会从后端获取一个新的副本。

 acl spider { "127.0.0.1"; /* or whereever the spider comes from */ } sub vcl_recv { if (client.ip ~ spider) { set req.hash_always_miss = true; } /* ... and continue as normal with the rest of the config */ } 

当这种情况发生时,直到新caching中出现新的响应,客户端将继续无缝地获取早期的caching(只要仍在TTL内)。

谢恩的回答比这个更好。 这是一个更复杂的解决scheme,还有其他问题。 请高兴Shane的回应,而不是这个。 我只是展示解决问题的另一种方法。


我最初的想法是return (pass);vcl_recv ,然后,在获取请求之后,在vcl_fetch ,以某种方式指示Varnish它应该caching该对象,甚至认为它早已明确地通过了。

事实certificate, 这是不可能的 :

如果您select在早期的VCL函数(例如:vcl_recv)中传递请求,您仍将执行vcl_fetch的逻辑,但即使提供caching时间,对象也不会进入caching。

因此,下一个最好的事情就是像普通的请求那样触发查询,但要确保它总是失败。 没有办法影响查找过程,所以它总是会打(假设它caching;如果不是,那么它将会错过和存储)。 但是我们可以影响vcl_hit

 sub vcl_hit { # is this our spider? if (req.http.user-agent ~ "Wget" && client.ip ~ spider) { # it's the spider, so purge the existing object set obj.ttl = 0s; return (restart); } return (deliver); } 

我们不能强迫它不使用caching,但我们可以从caching中清除对象,并重新启动整个过程。 现在回到开始,在vcl_recv ,它最终做了另一个查找。 由于我们已经清除了我们正在尝试更新的对象,因此它将会丢失,然后获取数据并更新caching。

有点复杂,但它的工作原理。 用户在清除和被存储的响应之间卡住的唯一窗口是单个请求处理的时间。 不完美,但很好。