理解它

理解它

我对 Varnish 和反向代理还不熟悉。我正在一个类似博客的应用程序中测试 Varnish,其中有一个页面,其中的“updated_at”会在页面更新后发生变化。因此,我决定我的缓存策略应该基于上次修改的标头。这样做的原因是,一旦页面在后台被修改,用户希望立即看到更改。

除此之外,我知道我可以向 cache-control 添加一个带有 must-revalidate 的 s-maxage,这样如果 last-modified 没有改变,Varnish 甚至不会尝试发出新的请求。

我还为浏览器添加了一个过期时间,这样就会有一个客户端缓存。这样,浏览器甚至不会要求 varnish 再次向 Apache 发出请求。

但是,我注意到,即使使用 must-revalidate,cache-control s-maxage 的优先级也高于 last-modified。此外,即使我不添加 cache-control,'last-modified' 也不起作用。Varnish 使用其默认 ttl,什么也没发生。我做错了什么?

我正在使用 Symfony,这些是标题:

$response = new Response();
$response->setPublic();

// expiration model for the browser cache (EXPIRE)
// the browser will only make a new request to Varnish again after ten minutes (600 seconds)
$date = new \DateTime();
$date->modify('+600 seconds');
$response->setExpires($date);

// expiration model for Varnish (CACHE-CONTROL)
// Varnish will only make a new request to Apache again after one hour (3600 seconds)
// The must-revalidate tells Varnish to do this request before serving the files after one hour (it's already de default behaviour)
// cache-control has priority over expire
//$response->setSharedMaxAge(3600);
$response->headers->addCacheControlDirective('must-revalidate', true);

// validation model for varnish (LAST-MODIFIED)
// Varnish will only make a new request to Apache again if the updated_at of the page changed even if the expiration time is ended
$response->setLastModified($page->getUpdatedAt());

// if the response didn't change, stop here
if ($response->isNotModified($request)) {
    return $response;
}

这是我第一次 MISS 和第二次 HIT 时的标头。这样,不管上次修改是否更改,标头始终与第二次相同。(我的浏览器缓存器已禁用,因此标头为 200,而不是 304)

第一个请求

第二个请求

答案1

不存在“上次修改无效”的情况。此标头仅指示资源上次修改的日期。客户端可能会在之后发出“如果此后未修改”请求,但这对您的情况并不重要。

后续请求自然会返回完全相同的标头。Varnish 中的对象被缓存,包括标头信息。因此,当 Varnish 提取缓存条目时,它将返回其精确副本。

理解它

您要同时处理两个缓存:Varnish 和浏览器缓存。每个请求只有一组 HTTP 标头。您不能为浏览器指定一个 HTTP Expires,然后为 Varnish 指定另一个。

因此,如果您想以不同的方式缓存内容(并且您确实这么做了),一种解决方案是beresp.ttl在 Varnish 中调整您想要放松 PHP 后端的时间量,即:24 小时。

VCL 中的某处:

sub vcl_backend_response {
    # A TTL of 24h
    # set beresp.ttl = 24h;
}

然后,考虑到您保留现有的 PHP 代码,Varnish 会将对页面的第一个请求缓存 24 小时,并使其在 10 分钟内可被浏览器缓存。

文章更新后,您必须清除 Varnish 缓存,也称为缓存失效。请参阅这一页(滚动到底部)。

原因是用户希望在后台修改页面后立即看到变化。

但你却希望它们有 10 分钟的浏览器缓存:)

相关内容