这实际上是一个非常好的和有效的问题,也是一个非常常见的反向代理问题。
问题是只有一个 Cache-Control 属性,它适用于客户端浏览器(私有缓存)和/或代理服务器(共享缓存)。如果您根本不希望 3rd 方代理缓存您的内容,并且希望您的 Varnish(或 Rails 后端)处理每个请求,则必须从 Varnish 发送适当的 Cache-Control 标头。
修改后端发送的 Cache-Control 标头在https://www.varnish-cache.org/trac/wiki/VCLExampleLongerCaching有详细讨论
你可以从两个不同的角度来解决这个问题。如果你想在 Rails 后端定义 max-age,例如为不同的对象指定不同的 TTL,你可以使用上面链接中描述的方法。
另一种解决方案是根本不从后端发送 Cache-Control 标头,而是在 varnish vcl_fetch() 中为对象定义所需的 TTL。这是我们采取的方法。
我们在 Varnish 中有一个 600 秒的默认 TTL,并为在进行更改时明确清除的页面定义更长的 TTL。这是我们当前的 vcl_fetch() 定义:
sub vcl_fetch {
if (req.http.Host ~ "(forum|discus)") {
# Forum pages are purged explicitly, so cache them for 48h
set beresp.ttl = 48h;
}
if (req.url ~ "^/software/") {
# Software pages are purged explicitly, so cache them for 48h
set beresp.ttl = 48h;
}
if (req.url ~ "^/search/forum_search_results" ) {
# We don't want forum search results to be cached for longer than 5 minutes
set beresp.ttl = 300s;
}
if(req.url == "/robots.txt") {
# Robots.txt is updated rarely and should be cached for 4 days
# Purge manually as required
set beresp.ttl = 96h;
}
if(beresp.status == 404) {
# Cache 404 responses for 15 seconds
set beresp.http.Cache-Control = "max-age=15";
set beresp.ttl = 15s;
set beresp.grace = 15s;
}
}
在我们的例子中,我们根本不从 Web 后端服务器发送 Cache-Control 标头。