0

好的,所以我正在尝试让 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 配置,X-Cacheable: NO:Not Cacheable如果 beresp.ttl 小于或等于 0,则设置标头。

为什么?

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

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

启动 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";
    }
}
4

1 回答 1

1

如果存在 cookie,Varnish 不会按照设计从缓存中获取任何请求。通常 cookie 表明响应对于特定用户是唯一的。

如果您不关心 cookie,或者如果您想保留特定的 cookie,您可以完全unset req.http.Cookie;参与vcl_recv()

if(req.http.Cookie) {
  if (req.http.Cookie !~ "(important_cookie|php_session)" ) {
    remove req.http.Cookie;
  }
}
于 2012-12-14T11:15:07.127 回答