多个域名使用Nginx、Varnish和Django都返回相同的缓存页面。

问题描述 投票:0回答:1

我正试图为一个现有的项目配置第二个域,之前只是使用一个域。但是Varnish总是从第一个域返回缓存的页面,所以当我访问第二个域时,我看到的是第一个域的内容。所以当我访问第二个域时,我看到的是第一个域的内容。我的配置如下。

注意:

  • 99%的配置已经存在了
  • 为了让这个帖子更清晰,我更改了域名,并删除了一些SLL配置。
  • 两个域名都使用相同的html页面,但内容略有不同。
  • 我对nginx和varnish不了解。

NGINX

server_tokens off;                                                                                             
resolver 127.0.0.53 ipv6=off;                                                                                  
upstream django_app_server {                                                                                   
    server unix:/home/test/run/gunicorn.sock fail_timeout=0;                                                 
}                                                                                                              

#http redirect too https.                                                                                      
server {                                                                                                       
    listen 80 default_server;                                                                                  
    server_name _;                                                                                             
    return 301 https://$host$request_uri;                                                                      
}                                                                                                              

server {                                                                                                       
    server_name existingdomain.com newdomain.com;                                                                                                                                                                 
    listen 443 ssl default deferred;                                                              

    # match with actual application server                                                                     
    client_max_body_size 10M;                                                                                  
    keepalive_timeout 60s;                                                                                     

    # proxy the request through varnish before sending it to gunicorn.        
    location / {
        proxy_pass http://127.0.0.1:6081;
    }
}
server {

    listen 8000;
    server_name existingdomain.com newdomain.com;
    root /home/test/www;

    location / {
        proxy_pass_header Server;
        proxy_redirect off;
        proxy_connect_timeout 60;
        proxy_read_timeout 60;
        proxy_set_header Host existingdomain.com; #changed to $host but results in 127.0.0.1 instead of domains
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_pass http://django_app_server;
    }

    client_max_body_size 10M;
    keepalive_timeout 60s;
}

VARNISH

vcl 4.0;

import std;
import directors;

acl purgers {
    "localhost";
}

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

sub vcl_recv {

    # uncruft
    unset req.http.User-Agent;
    unset req.http.Accept;
    unset req.http.Accept-Language;

    # Normalize the query arguments
    set req.url = std.querysort(req.url);

    # Fix client IP forwarding
    # Note: this expects Varnish to be behind upstream that sets this securely
        if (req.http.x-forwarded-for) {
            set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
        } else {
            set req.http.X-Forwarded-For = client.ip;
        }
    }

    # allow purge
    if (req.method == "PURGE") {
        if (client.ip ~ purgers) {
            return(purge);
        } else {
            return(synth(403, "Access denied."));
        }
    }
    elif (req.method == "BAN") {
        if (client.ip ~ purgers) {
            # assumes the ``X-Ban`` header is a regex
            ban("obj.http.x-url ~ " + req.http.x-ban);
            return(synth(200, "Ban added"));
        } else {
            return(synth(403, "Access denied."));
        }
    }
    # only head/get
    if (req.method != "GET" && req.method != "HEAD") {
        return(pass);
    }

    # kill cookies for everything else
    unset req.http.Cookie;
    return(hash);
}

sub vcl_backend_response {
    # keep for lurker bans
    set beresp.http.x-url = bereq.url;

    # do the gzip dance with nginx
    if (beresp.http.content-type ~ "^text/" || beresp.http.content-type ~ "^application/json") {
        set beresp.do_gzip = true;
    }

    if (beresp.ttl <= 0s || beresp.http.Cache-Control ~ "no-cache|no-store|private") {
        # mark as "Hit-For-Pass"
    if (beresp.ttl <= 0s || beresp.http.Cache-Control ~ "no-cache|no-store|private") {
        # mark as "Hit-For-Pass"
        set beresp.ttl = 1m;
        set beresp.uncacheable = true;
        return (deliver);
    }
    # stop server error hammering
    if (beresp.status == 500 || beresp.status == 502 || beresp.status == 503 || beresp.status == 504) {
        set beresp.ttl = 5s;
        unset beresp.http.Set-Cookie;
        return (deliver);
    }
    # stop 404 hammering
    if (beresp.status == 404) {
        set beresp.ttl = 10s;
        unset beresp.http.Set-Cookie;
        return (deliver);
    }
    # don't cache 40x responses
    if (beresp.status == 400 || beresp.status == 401 || beresp.status == 402 || beresp.status == 403) {
        set beresp.ttl = 5m;
        set beresp.uncacheable = true;
        unset beresp.http.Set-Cookie;
        return (deliver);
    }

    unset beresp.http.Set-Cookie;
    set beresp.grace = 2m;
    set beresp.ttl = 5m;

    return (deliver);
}

sub vcl_deliver {
    # for internal use only
    unset resp.http.x-url;

    # debug info
    if (obj.hits > 0) {
        set resp.http.X-Cache = "hit";
    } else {
        set resp.http.X-Cache = "miss";
    }
    # set resp.http.X-Cache-Hits = obj.hits;

    # cleanup headers
  # cleanup headers
    unset resp.http.Server;
    unset resp.http.X-Varnish;
    unset resp.http.Via;

    return (deliver);
}

sub vcl_purge {
    # only handle actual PURGE HTTP methods, everything else is discarded
    if (req.method != "PURGE") {
        # restart request
        set req.http.X-Purge = "Yes";
        return(restart);
    }
}

我试过了。

  • 将NGINX: proxy_set_header Host existingdomain.com; 改为 proxy_set_header Host $host;
  • 将NGINX: 2服务器配置列表改为两个域的8000端口。
  • 改变了VARNISH:两个域的2个后台配置。

我想要什么。

  • 最终,我想要2个不同的域名和几个子域名都需要自己的varnish缓存。
django nginx caching varnish
1个回答
1
投票
# proxy the request through varnish before sending it to gunicorn.        
location / {
    proxy_pass http://127.0.0.1:6081;
}

你没有传递任何细节给Varnish。所以Varnish无法确定要使用哪个域。也许是这样的

  proxy_set_header        Host $host;
  proxy_set_header        X-Real-IP $remote_addr;
  proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header        X-Forwarded-Proto $scheme;
  proxy_pass              http://127.0.0.1:6081;

再加上像其他人所说的,你需要更新你要发送的主机。gunicorn


1
投票

下面的配置行。

proxy_set_header Host existingdomain.com;

发送相同的 Host: 头的两个域名。

应该是这样的。

proxy_set_header Host $host;

另一个答案提到 $hostname 变量,这是不正确的,因为它代表机器名称。而你想要的是 $host 因为这等于 Host: 头。


0
投票

下面的Nginx设置会导致Varnish只服务于来自于 existingdomain.com,即使其他主机被请求。

proxy_set_header Host existingdomain.com;

Varnish同时使用 网址主机名 来识别缓存中的对象。当您将主机名硬编码为 existingdomain.com 在Nginx中,你总是会得到相同的内容。

请将此设置改为以下值。

proxy_set header Host $hostname;
© www.soinside.com 2019 - 2024. All rights reserved.