Varnish不会在没有过期标题的情况下缓存

时间:2012-11-17 17:12:18

标签: php caching cache-control varnish

在我的服务器上,我使用8080上的Apache在端口80上运行Varnish(缓存) 当我设置如下所示的标题时,Varnish缓存非常好:

    $this->getResponse()->setHeader('Expires', '', true);
    $this->getResponse()->setHeader('Cache-Control', 'public', true);
    $this->getResponse()->setHeader('Cache-Control', 'max-age=2592000');
    $this->getResponse()->setHeader('Pragma', '', true);

但是这意味着人们在没有检索新版本的情况下缓存我的网站 当我删除标题时,人们会在每次重新加载页面时检索新版本(因此Varnish从不缓存)。

我无法弄清楚这里出了什么问题 我理想的情况是人们不会在客户端缓存html,而是将其留给Varnish。

3 个答案:

答案 0 :(得分:1)

  

我理想的情况是人们不会在客户端缓存html,而是将其留给Varnish。

你想要的是varnish来缓存资源并将其提供给客户端,并且只有在发生变化时才生成新版本。最简单的方法是长时间使用varnish cache,并在更改内容时使用varnish(使用PURGE命令)使条目无效。

默认情况下,varnish将其缓存规则基于后端提供的标头。因此,如果您的php代码生成您描述的标头,则默认的varnish vcl将相应地调整其缓存策略。但是,它只能以通用,安全的方式执行此操作(例如,如果您使用cookie,它将永远不会缓存)。你知道你的后端是如何工作的,你应该改变varnish的缓存行为,而不是通过从后端发送不同的头文件,而是写一个清漆.vcl文件。您应该告诉varnish长时间缓存资源,即使缺少Max-Age标头的Cache-Control(在.vcl文件中设置TimeToLive ttl)。然后,Varnish将为生成的条目提供服务,直到ttl通过或您清除了条目。

如果你有这个工作,那就有一个更高级的选择:在客户端缓存资源,但每次想要使用它时让客户端“重新验证”它。浏览器使用HTTP GET加If-Modified-Since标头执行此操作(您的响应应包含Date标头以激发其行为)或If-Match标头(您的回复应包含ETAG标题来挑起他的行为)。这节省了带宽,因为清漆可以响应304 NOT-MODIFIED响应,而无需再次发送整个资源。

答案 1 :(得分:0)

最简单的方法就是将最大年龄调低到更合理的水平。目前,您将其设置为30天。尝试将其设置为15分钟:

$this->getResponse()->setHeader('Cache-Control', 'max-age=900');

Web缓存是一个有点复杂的主题,由于一些非常不同的客户端解释而加剧。但总的来说,这将减轻Web服务器的负担,同时确保在合理的时间范围内提供新内容。

答案 2 :(得分:0)

将客户端缓存的标准HTTP标头设置为您想要的任何内容。设置只有Varnish会看到的自定义标题,例如X-Varnish-TTL然后在您的VCL中,将以下代码合并到vcl_fetch子目录中:

if (beresp.http.X-Varnish-TTL) {
    C{
        char *ttl;
        /* first char in third param is length of header plus colon in octal */
        ttl = VRT_GetHdr(sp, HDR_BERESP, "\016X-Varnish-TTL:");
        VRT_l_beresp_ttl(sp, atoi(ttl));
    }C
    unset beresp.http.X-Varnish-TTL;  // Remove so client never sees this
}