2

在我的服务器上,我在端口 80 上运行 Varnish(缓存),Apache 在 8080 上。
当我设置如下标头时,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。

4

3 回答 3

1

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

您想要的是 varnish 缓存资源并将其提供给客户端,并且仅在发生更改时才生成新版本。最简单的方法是让 varnish 将其缓存很长时间,并在这种情况发生变化时使 varnish 中的条目无效(使用 PURGE 命令)。

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

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

于 2012-11-18T23:12:18.763 回答
0

最简单的方法就是将 max-age 调低到更合理的值。目前,您已将其设置为 30 天。尝试将其设置为 15 分钟:

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

Web 缓存是一个有点复杂的话题,一些非常不同的客户端解释加剧了这种情况。但总的来说,这将减轻 Web 服务器的负载,同时确保新内容在合理的时间范围内可用。

于 2012-11-17T17:19:39.543 回答
0

将客户端缓存的标准 HTTP 标头设置为您想要的任何内容。设置一个只有 Varnish 才能看到的自定义标头,例如X-Varnish-TTLThen 在您的 VCL 中,将以下代码合并到您的vcl_fetchsub 中:

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
}
于 2013-03-07T19:34:55.227 回答