Varnish 提供错误的文件

Varnish serves wrong files

我在 nging 后面使用 varnish 3 将多个站点代理到一个域中。 基本设置工作正常,但如果文件名已存在于它的缓存中,我现在遇到清漆服务错误文件的问题。 基本上我在 default.vcl 中所做的就是:

   if(req.url ~ "^/foo1") {
        set req.backend = foo1;
        set req.url = regsub(req.url, "^/foo1/", "/");
    }
    else if(req.url ~ "^/foo2") {
        set req.backend = foo2;
        set req.url = regsub(req.url, "^/foo2/", "/");
    }

如果我现在调用 /foo1/index.html,/foo2/index.html 将提供相同的文件。在重新启动 varnish 并调用 /foo2/index.html 后,/foo1/index.html 将服务于 foo2 的 index.html.

据我所知,这是创建哈希的问题,它不考虑使用的后端,但只考虑 url(缩短后)和域:

    11 VCL_call     c hash
    11 Hash         c /index.html
    11 Hash         c mydomain

我现在通过改变我的 vcl_hash 也使用后端解决了这个问题,但我相信一定有更好、更方便的方法:

    sub vcl_hash {
      hash_data(req.url);
      hash_data(req.backend);
    }

任何提示将不胜感激,非常感谢!

你有两种不同的方法来做到这一点。第一个是通过在 vcl_hash.

中添加额外值(例如 req.backend)来执行您的建议
sub vcl_hash {
   hash_data(req.url);
   hash_data(req.backend);
}

第二种方式,不更新vcl_recv中的req,只更新vcl_miss/pass中的bereq

sub vcl_urlrewrite {
    if(req.url ~ "^/foo1") {
        set bereq.url = regsub(req.url, "^/foo1/", "/");
    }
    else if(req.url ~ "^/foo2") {
        set bereq.url = regsub(req.url, "^/foo2/", "/");
    }
}
sub vcl_miss {
    call vcl_urlrewrite;
}
sub vcl_pass {
    call vcl_urlrewrite;
}
sub vcl_pipe {
    call vcl_urlrewrite;
}

第二种方法需要更多的 VCL,但它也有一些优点。例如,当使用 varnishlog 分析日志时,您可以看到原始请求(c 列),以及更新后的后端请求(b 列)。

$ varnishlog /any-options-here/
(..)
   xx RxURL        c /foo1/index.html
(..)
   xx TxURL        c /index.html
(..)
$