清漆缓存和标题

时间:2017-07-30 16:50:48

标签: caching varnish varnish-vcl

我正在尝试缓存我的网络应用的某个部分。

我在http://website.dev/pictures/:id有一个端点,它返回PHP生成的图片。有时,端点可以在查询字符串中带有宽度和高度,以定义图片尺寸:http://website.dev/pictures/:id?w=100&h=100

所以我想在很长一段时间内缓存这些请求。

我尝试了一个非常简单的VCL,因为我是新手,并且我不想做复杂的事情:

vcl 4.0;


backend default {
    .host = "127.0.0.1";
    .port = "80";
}

sub vcl_recv {
    if (req.url ~ "^/api/pictures" && req.method ~ "GET") {
        # I heard that it was better to unset the cookies here to allow cache
        unset req.http.cookie;
        return (hash);
    }

    return (pass);
}

sub vcl_deliver {
    if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT";
    } else {
        set resp.http.X-Cache = "MISS";
    }
}

但是现在,我根据我的要求得到了所有的MISS。我试图修改来自我的后端的响应,以便有适当的缓存控制和过期标题:

Response Headers:
Accept-Ranges:bytes
Age:0
Cache-Control:max-age=10000, private
Connection:keep-alive
Content-Length:96552
Content-Type:image/jpeg
Date:Sun, 30 Jul 2017 16:41:58 GMT
Expires:Fri, 01 Jan 2100 00:00:00 GMT
Server:nginx/1.10.3 (Ubuntu)
Via:1.1 varnish (Varnish/5.1)
X-Cache:MISS
X-RateLimit-Limit:60
X-RateLimit-Remaining:57
X-Varnish:32772

Request Headers
view source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding:gzip, deflate
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4,es;q=0.2
Cache-Control:max-age=0
Connection:keep-alive
Cookie:_ga=xxxxxxxxxxxxx
Host:website.dev:6081
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36

我在哪里错了?我怎样才能确定这些端点上的请求并且仅在很长时间内被Varnish缓存?

1 个答案:

答案 0 :(得分:2)

它没有按预期缓存的原因是因为您的Web应用程序正在发送:

  

缓存控制:max-age = 10000,私有

内置VCL逻辑prevents caching in presence of Cache-Control: private

此处的最佳做法是修复您的应用:要么坚持使用Cache-Control public 类型,要么将其删除并仅保留Expires标题。< / p>

如果您不愿意修复该应用或有理由不这样做,您需要添加一些VCL。以下内容将确保&#34;内置VCL逻辑&#34;上面提到的不会阻止Cache-Control: private存在的缓存:

sub vcl_backend_response {
    if (beresp.ttl <= 0s ||
      beresp.http.Set-Cookie ||
      beresp.http.Surrogate-control ~ "no-store" ||
      (!beresp.http.Surrogate-Control &&
        beresp.http.Cache-Control ~ "no-cache|no-store") ||
      beresp.http.Vary == "*") {
        /*
        * Mark as "Hit-For-Pass" for the next 2 minutes
        */
        set beresp.ttl = 120s;
        set beresp.uncacheable = true;
    }
    return (deliver);
}

最后,当您的应用为缓存发送正确的Expires标头时,Varnish会忽略它,因为Cache-Control标头优先于它。 (根据HTTP规范)。请注意它,因为它的值将用作Varnish缓存对象的持续时间。 (而不是来自Expires)的价值