RiESA
V2EX  ›  问与答

一个 Varnish 服务如何对运行在一个 nginx 上的不同网站分开缓存?

  •  
  •   RiESA · Feb 14, 2020 · 1592 views
    This topic created in 2282 days ago, the information mentioned may be changed or developed.

    如题,第一次使用配置 Varnish,发现把两个网站都接入 Varnish 之后,缓存会混淆,极有可能是我配置的问题

    nginx 运行在 80 端口 Varnish 运行在 8080 端口,并且监听 nginx 所在的 80 端口,并且目前两个网站都是 80 端口

    配置文件我只写了一个 backend

    default.vcl

    vcl 4.0;

    backend default {

    .host = "127.0.0.1";
    
    .port = "80";
    

    }

    ...............后略

    我个人思考了一下,是不是我想问题太简单粗暴了,我以为 nginx 已经配置好的情况下,通过 Varnish,会根据 nginx 的配置把不同的站点分开对待,没想到缓存在一起了

    当然也和我没配置写对有关,是不是应该把其中的一个网站的端口改成别的,例如 81,然后加多一个 backend ?例如

    vcl 4.0;

    backend default {

    .host = "127.0.0.1";
    
    .port = "80";
    

    } backend default2 {

    .host = "127.0.0.1";
    
    .port = "81";
    

    }

    但是我又不太确定这样是否正确,单单把端口分开可以解决这种情况吗?还是需要其他的配置让 Varnish 区分开两个网站的缓存,希望有经验的大佬解答一下,第一次接触这个两眼一抹黑

    12 replies    2020-02-15 14:27:15 +08:00
    RiESA
        1
    RiESA  
    OP
       Feb 14, 2020 via Android
    打捞一下自己 orz
    34
        2
    34  
       Feb 14, 2020
    这个 Varnish 是放在 nginx 前面做缓存加速? 看不懂帮顶。
    sleepm
        3
    sleepm  
       Feb 14, 2020 via Android
    就是需要多个 backend
    先是 nginx 转发给 varnish
    然后 varnish 根据规则再转发给后面不同端口的 backend

    可以参考
    https://xn--vkuk.org/blog/%e6%8a%98%e8%85%benginx-varnish-apache2-https%e6%95%b4%e7%ab%99%e5%b0%8f%e8%ae%b0/
    现在想想最后面不同的端口也可以由 nginx 提供
    现在不用 varnish 了。。就是因为缓存太变态了。。搞个啥都得重启清下缓存,要不怀疑人生,哈哈
    RiESA
        4
    RiESA  
    OP
       Feb 14, 2020 via Android
    @sleepm 好的谢谢,我研究一下
    RiESA
        5
    RiESA  
    OP
       Feb 14, 2020 via Android
    @sleepm 我是直接 访问>varnish>nginx 这样的结构,前面并没有多一层 nginx,这样的话单纯区分两个站的端口可以解决缓存混淆问题吗?
    sleepm
        6
    sleepm  
       Feb 14, 2020 via Android
    主要是 varnish 的规则
    我把 nginx 放前面就是为了 https,那会 varnish 还不支持 https
    RiESA
        7
    RiESA  
    OP
       Feb 14, 2020 via Android
    @sleepm 好的,谢谢
    RiESA
        8
    RiESA  
    OP
       Feb 15, 2020
    @sleepm 我又来请教您了,我昨晚尝试配置了一下多站点,但是出现了一个很奇怪的问题,站点 A,也就是第一个 backend 完全正常,第二个 backend,站点 B 会出现 404 的情况,但是又不是完全 404 强刷一下页面可以出来,但是没点几下又 404 这种,
    目前的访问流程是:CDN>varnish>nginx,不排除是我设置写的有问题,不知道能不能帮我看看,谢谢
    RiESA
        9
    RiESA  
    OP
       Feb 15, 2020
    vcl 4.0;
    # set default backend if no server cluster specified
    backend default {
    .host = "127.0.0.1";
    .port = "80";
    }
    backend test {
    .host = "127.0.0.1";
    .port = "81";
    }


    # access control list for "purge": open to only localhost and other local nodes
    acl purge {
    "127.0.0.1";
    }

    # vcl_recv is called whenever a request is received
    sub vcl_recv {
    # Serve objects up to 2 minutes past their expiry if the backend
    # is slow to respond.
    # set req.grace = 120s;
    if(req.http.host ~ "a.com"){
    set req.http.host = "a.com";
    set req.backend_hint = default;
    }
    if(req.http.host ~ "b.com"){
    set req.http.host = "b.com";
    set req.backend_hint = blog;
    set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
    set req.backend_hint= default;

    # This uses the ACL action called "purge". Basically if a request to
    # PURGE the cache comes from anywhere other than localhost, ignore it.
    if (req.method == "PURGE") {
    if (!client.ip ~ purge) {
    return (synth(405, "Not allowed."));
    } else {
    return (purge);
    }
    }

    # Pass any requests that Varnish does not understand straight to the backend.
    if (req.method != "GET" && req.method != "HEAD" &&
    req.method != "PUT" && req.method != "POST" &&
    req.method != "TRACE" && req.method != "OPTIONS" &&
    req.method != "DELETE") {
    return (pipe);
    } /* Non-RFC2616 or CONNECT which is weird. */

    # Pass anything other than GET and HEAD directly.
    if (req.method != "GET" && req.method != "HEAD") {
    return (pass);
    } /* We only deal with GET and HEAD by default */

    # Pass requests from logged-in users directly.
    # Only detect cookies with "session" and "Token" in file name, otherwise nothing get cached.
    if (req.http.Authorization || req.http.Cookie ~ "session" || req.http.Cookie ~ "Token") {
    return (pass);
    } /* Not cacheable by default */

    # normalize Accept-Encoding to reduce vary
    if (req.http.Accept-Encoding) {
    if (req.http.User-Agent ~ "MSIE 6") {
    unset req.http.Accept-Encoding;
    } elsif (req.http.Accept-Encoding ~ "gzip") {
    set req.http.Accept-Encoding = "gzip";
    } elsif (req.http.Accept-Encoding ~ "deflate") {
    set req.http.Accept-Encoding = "deflate";
    } else {
    unset req.http.Accept-Encoding;
    }
    }

    return (hash);
    }


    sub vcl_pipe {
    # Note that only the first request to the backend will have
    # X-Forwarded-For set. If you use X-Forwarded-For and want to
    # have it set for all requests, make sure to have:
    # set req.http.connection = "close";

    # This is otherwise not necessary if you do not do any request rewriting.

    set req.http.connection = "close";
    }

    # Called if the cache has a copy of the page.
    sub vcl_hit {
    if (!obj.ttl > 0s) {
    return (pass);
    }

    # Force lookup if the request is a no-cache request from the client.
    if (req.http.Cache-Control ~ "no-cache") {
    return (miss);
    }
    }

    # Called after a document has been successfully retrieved from the backend.
    sub vcl_backend_response {
    # set minimum timeouts to auto-discard stored objects
    set beresp.grace = 120s;

    if (beresp.ttl < 48h) {
    set beresp.ttl = 48h;
    }

    if (!beresp.ttl > 0s) {
    set beresp.uncacheable = true;
    return (deliver);
    }

    if (beresp.http.Set-Cookie) {
    set beresp.uncacheable = true;
    return (deliver);
    }

    # if (beresp.http.Cache-Control ~ "(private|no-cache|no-store)") {
    # set beresp.uncacheable = true;
    # return (deliver);
    # }

    if (beresp.http.Authorization && !beresp.http.Cache-Control ~ "public") {
    set beresp.uncacheable = true;
    return (deliver);
    }

    return (deliver);
    }
    RiESA
        10
    RiESA  
    OP
       Feb 15, 2020
    更正一下,目前是下面这个才对,上面那个忘记改一个地方了
    RiESA
        11
    RiESA  
    OP
       Feb 15, 2020
    vcl 4.0;
    # set default backend if no server cluster specified
    backend default {
    .host = "127.0.0.1";
    .port = "80";
    }
    backend test {
    .host = "127.0.0.1";
    .port = "81";
    }


    # access control list for "purge": open to only localhost and other local nodes
    acl purge {
    "127.0.0.1";
    }

    # vcl_recv is called whenever a request is received
    sub vcl_recv {
    # Serve objects up to 2 minutes past their expiry if the backend
    # is slow to respond.
    # set req.grace = 120s;
    if(req.http.host ~ "a.cn"){
    set req.http.host = "a.cn";
    set req.backend_hint = default;
    }
    if(req.http.host ~ "b.cn"){
    set req.http.host = "b.cn";
    set req.backend_hint = test;
    set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
    set req.backend_hint= default;

    # This uses the ACL action called "purge". Basically if a request to
    # PURGE the cache comes from anywhere other than localhost, ignore it.
    if (req.method == "PURGE") {
    if (!client.ip ~ purge) {
    return (synth(405, "Not allowed."));
    } else {
    return (purge);
    }
    }

    # Pass any requests that Varnish does not understand straight to the backend.
    if (req.method != "GET" && req.method != "HEAD" &&
    req.method != "PUT" && req.method != "POST" &&
    req.method != "TRACE" && req.method != "OPTIONS" &&
    req.method != "DELETE") {
    return (pipe);
    } /* Non-RFC2616 or CONNECT which is weird. */

    # Pass anything other than GET and HEAD directly.
    if (req.method != "GET" && req.method != "HEAD") {
    return (pass);
    } /* We only deal with GET and HEAD by default */

    # Pass requests from logged-in users directly.
    # Only detect cookies with "session" and "Token" in file name, otherwise nothing get cached.
    if (req.http.Authorization || req.http.Cookie ~ "session" || req.http.Cookie ~ "Token") {
    return (pass);
    } /* Not cacheable by default */

    # normalize Accept-Encoding to reduce vary
    if (req.http.Accept-Encoding) {
    if (req.http.User-Agent ~ "MSIE 6") {
    unset req.http.Accept-Encoding;
    } elsif (req.http.Accept-Encoding ~ "gzip") {
    set req.http.Accept-Encoding = "gzip";
    } elsif (req.http.Accept-Encoding ~ "deflate") {
    set req.http.Accept-Encoding = "deflate";
    } else {
    unset req.http.Accept-Encoding;
    }
    }

    return (hash);
    }


    sub vcl_pipe {
    # Note that only the first request to the backend will have
    # X-Forwarded-For set. If you use X-Forwarded-For and want to
    # have it set for all requests, make sure to have:
    # set req.http.connection = "close";

    # This is otherwise not necessary if you do not do any request rewriting.

    set req.http.connection = "close";
    }

    # Called if the cache has a copy of the page.
    sub vcl_hit {
    if (!obj.ttl > 0s) {
    return (pass);
    }

    # Force lookup if the request is a no-cache request from the client.
    if (req.http.Cache-Control ~ "no-cache") {
    return (miss);
    }
    }

    # Called after a document has been successfully retrieved from the backend.
    sub vcl_backend_response {
    # set minimum timeouts to auto-discard stored objects
    set beresp.grace = 120s;

    if (beresp.ttl < 48h) {
    set beresp.ttl = 48h;
    }

    if (!beresp.ttl > 0s) {
    set beresp.uncacheable = true;
    return (deliver);
    }

    if (beresp.http.Set-Cookie) {
    set beresp.uncacheable = true;
    return (deliver);
    }

    # if (beresp.http.Cache-Control ~ "(private|no-cache|no-store)") {
    # set beresp.uncacheable = true;
    # return (deliver);
    # }

    if (beresp.http.Authorization && !beresp.http.Cache-Control ~ "public") {
    set beresp.uncacheable = true;
    return (deliver);
    }

    return (deliver);
    }
    sleepm
        12
    sleepm  
       Feb 15, 2020
    规则没问题,那估计就是你的 cdn 设置的回源有问题
    看看回源设置,不行的话撤了 cdn 试试,如果撤了没问题,那就是 cdn 的设置了
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5941 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 58ms · UTC 03:03 · PVG 11:03 · LAX 20:03 · JFK 23:03
    ♥ Do have faith in what you're doing.