将Cookie添加到Varnish中的请求时,为什么将beresp.ttl设置为0?

时间:2012-12-14 11:06:24

标签: varnish http-caching varnish-vcl

好的,所以我试图使Varnish正常工作,我有一个奇怪的行为,我无法解释(可能是由于缺乏理解)。

这是我正在尝试做的事情:

GET http://scm.dev:6081/articles
If-None-Match: "50a0794aaca51fce202e86da428b7dca9b4bbff93"

我得到了:

HTTP/1.1 200 OK
Age: 3                                    // Correctly using a cached result
Content-Length: 3878
Content-Type: application/json
Date: Fri, 14 Dec 2012 10:59:34 GMT
Via: 1.1 varnish
X-Cacheable: YES                          // It is correct
Cache-Control: max-age=10, public, s-maxage=20
Etag: "50a0794aca51fce202e86da428b7dca9b4bbff93"
Vary: Accept,Accept-Encoding

现在,如果我在我的请求中添加Cookie:

GET http://scm.dev:6081/articles
If-None-Match: "50a0794aaca51fce202e86da428b7dca9b4bbff93"
Cookie: foo=bar

我收到非缓存响应和非缓存警告:

HTTP/1.1 200 OK
Age: 0                                    // Always set to 0
Content-Length: 3878
Content-Type: application/json
Date: Fri, 14 Dec 2012 10:59:34 GMT
Via: 1.1 varnish
X-Cacheable: NO:Not Cacheable             // It is not correct
Cache-Control: max-age=10, public, s-maxage=20
Etag: "50a0794aca51fce202e86da428b7dca9b4bbff93"
Vary: Accept,Accept-Encoding

如果检查后面的vcl配置,如果beresp.ttl小于或等于0,则设置X-Cacheable: NO:Not Cacheable标头。

为什么?

我还假设应该缓存一个Cookie返回Cache-Control: public的请求,只要后端承担正确设置public参数的责任。

我会假设在使用Cookie发出请求时会设置X-Cacheable: NO:Got Session,但它甚至不会更进一步。

启动varnish守护程序的命令行:

/usr/sbin/varnishd -P /var/run/varnishd.pid -a :6081 -T 192.168.1.100:6082 -f /etc/varnish/custom.vcl -S /etc/varnish/secret -s malloc,256m

这是我的custom.vcl

backend scm {
.host = "scm.dev";
.port = "80";
}

sub vcl_recv {
    set req.http.Surrogate-Capability = "abc=ESI/1.0";
}

sub vcl_fetch {
    if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
        unset beresp.http.Surrogate-Control;
        set beresp.do_esi = true;
    }

    # Varnish determined the object was not cacheable
    if (beresp.ttl <= 0s) {
        set beresp.http.X-Cacheable = "NO:Not Cacheable";

    # You don't wish to cache content for logged in users
    } elsif (req.http.Cookie ~ "(foo)") {
        set beresp.http.X-Cacheable = "NO:Got Session";

        return(hit_for_pass);
    # You are respecting the Cache-Control=private header from the backend
    } elsif (beresp.http.Cache-Control ~ "private") {
        set beresp.http.X-Cacheable = "NO:Cache-Control=private";

        return(hit_for_pass);
    # Varnish determined the object was cacheable
    } else {
        set beresp.http.X-Cacheable = "YES";
    }

    return(deliver);
}

sub vcl_hit {
    if (req.request == "PURGE") {
        set obj.ttl = 0s;
        error 200 "Purged";
    }
}

sub vcl_miss {
    if (req.request == "PURGE") {
        error 404 "Not purged";
    }
}

1 个答案:

答案 0 :(得分:1)

如果存在cookie,

Varnish将不会从缓存中获取任何请求by design。通常,Cookie表示响应对特定用户而言是唯一的。

如果您不关心Cookie,或者您想要保留特定的Cookie,您可以完全unset req.http.Cookie; vcl_recv() {/ 1}}

if(req.http.Cookie) {
  if (req.http.Cookie !~ "(important_cookie|php_session)" ) {
    remove req.http.Cookie;
  }
}