简体   繁体   English

如何使用Cache-Control控制Varnish和浏览器:Rails环境中的max-age标头?

[英]Howto control Varnish and a Browser using Cache-Control: max-age Header in a Rails environment?

Recently I added a Varnish instance to a Rails application stack. 最近我在Rails应用程序堆栈中添加了一个Varnish实例。 Varnish in it's default configuration can be convinced from caching a certain resource using the Cache-Control Header like so: 可以通过使用Cache-Control Header缓存某个资源来确定其中的Varnish的默认配置,如下所示:

Cache-Control: max-age=86400, public=true

I achieved that one using the expires_in statement in my controllers: 我使用控制器中的expires_in语句实现了那个:

def index
  expires_in 24.hours, public: true
  respond_with 'some content'
end

That worked well. 这很好用。 What I did not expect is, that the Cache-Control header ALSO affects the browser. 我没想到的是,Cache-Control标头也会影响浏览器。 That leads to the problem that both - Varnish and my users browser cache a certain resource. 这导致了 - Varnish和我的用户浏览器都缓存某个资源的问题。 The resource is purged from varnish correctly, but the browser does not attempts to request it again unless max-age is reached. 资源将从varnish中正确清除,但除非达到max-age,否则浏览器不会再次尝试请求它。

So I wonder wether I should use 'expires_in' in combination with Varnish at all? 所以我想知道我应该将'expires_in'与Varnish结合使用吗? I could filter the Cache-Control header in a Nginx or Apache instance in front of Varnish, but that seems odd. 我可以在Varnish前面的Nginx或Apache实例中过滤Cache-Control标头,但这看起来很奇怪。

Can anyone enlighten me? 任何人都可以开导我吗?

Regards Felix 问菲利克斯

That is actually a very good and valid question, and a very common one with reverse proxies. 这实际上是一个非常好的有效问题,也是一个非常常见的反向代理问题。

The problem is that there's only one Cache-Control property and it is intended for the client browser (private cache) and/or a proxy server (shared cache). 问题是只有一个Cache-Control属性,它适用于客户端浏览器(私有缓存)和/或代理服务器(共享缓存)。 If you don't want 3rd party proxies to cache your content at all, and want every request to be served by your Varnish (or by your Rails backend), you must send appropriate Cache-Control header from Varnish. 如果您不希望第三方代理完全缓存您的内容,并希望每个请求都由您的Varnish(或您的Rails后端)提供,您必须从Varnish发送适当的Cache-Control标头。

Modifying Cache-Control header sent by the backend is discussed in detail at https://www.varnish-cache.org/trac/wiki/VCLExampleLongerCaching 修改后端发送的Cache-Control标头将在https://www.varnish-cache.org/trac/wiki/VCLExampleLongerCaching中详细讨论

You can approach the solution from two different angles. 您可以从两个不同的角度处理解决方案。 If you wish to define max-age at your Rails backend, for instance to specify different TTL for different objects, you can use the method described in the link above. 如果您希望在Rails后端定义max-age,例如为不同的对象指定不同的TTL,则可以使用上面链接中描述的方法。

Another solution is to not send Cache-Control headers at all from the backend, and instead define desirable TTLs for objects in varnish vcl_fetch(). 另一个解决方案是不从后端发送Cache-Control头,而是在varnish vcl_fetch()中为对象定义所需的TTL。 This is the approach we have taken. 这是我们采取的方法。

We have a default TTL of 600 seconds in Varnish, and define longer TTLs for pages that are definitely explicitly purged when changes are made. 我们在Varnish中有一个600秒的默认TTL,并为进行更改时明确清除的页面定义更长的TTL。 Here's our current vcl_fetch() definition: 这是我们当前的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;
  }
}

In our case we don't send Cache-Control headers at all from the web backend servers. 在我们的例子中,我们根本不从Web后端服务器发送Cache-Control头。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM