当混合命名服务器和默认服务器时,Nginx 流量会流向错误的上行方向

当混合命名服务器和默认服务器时,Nginx 流量会流向错误的上行方向

我有以下 nginx 配置文件。问题是所有流量都流向上游 clustera。如何配置 nginx 以仅将 example.com 的流量发送到 clustera,其余所有流量发送到 clusterb?

user www-data;
worker_processes  1;

error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    log_format cache '\n*** $remote_addr [$time_local] '
             '[$upstream_cache_status] $upstream_response_time '
             '$host "$request" ($status) $body_bytes_sent '
             '"$http_referer"  "$http_user_agent" '
             'Cache-Control: $upstream_http_cache_control '
             'Expires: $upstream_http_expires '
             ;

    access_log  /var/log/nginx/access.log cache;
    sendfile        on;
    keepalive_timeout  65;


    gzip    on;
    gzip_vary       on;
    gzip_comp_level 6;
    gzip_proxied    any;

    gzip_disable    "MSIE [1-6]\.(?!.*SV1)";
    gzip_buffers    16 8k;

    include /etc/nginx/conf.d/*.conf;

    proxy_cache_key "$scheme$host$request_uri";
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=main:10m max_size=1g inactive=30m;


    upstream clustera {
        ip_hash;
        server  a.example.com:80;
    }
    upstream clusterb {
        ip_hash;
        server  b.example.com:80;
    }


    client_max_body_size    20m;
    client_body_buffer_size 128k;
    proxy_connect_timeout      300;
    proxy_send_timeout         300;
    proxy_read_timeout         300;

    # host for example.com should send traffic to clustera
    server {
        listen 80;
        server_name example.com;

        location ~*(png|jpeg|jpg|gif|ico|css|js)$ {
            proxy_pass      http://clustera;
            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_cache     main;
            proxy_cache_valid       200 5m;
            proxy_cache_valid       302 1m;
        }

        location / {
            proxy_pass http://clustera;
            proxy_set_header        Host             $host;
            proxy_set_header        X-Real-IP        $remote_addr;
            proxy_set_header        X-Forwarded-For  $proxy_add_x_forwarded_for;
        }

    }
    # host for everyone else. traffic goes to clusterb
    server {
        listen 80;
        server_name _;

        if ( $http_user_agent ~* (spider|crawler|slurp) ) {
             return 503;
        }

        set $slow 0;
        if ( $http_user_agent ~* (bot) ) {
             set $slow 1;
        }

        if ( $slow ) {
           set $limit_rate 1k;
        }

        location ~*(png|jpeg|jpg|gif|ico|css|js)$ {
            proxy_pass      http://clusterb;

            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_cache     main;
            proxy_cache_valid       200 5m;
            proxy_cache_valid       302 1m;
        }

        location /images {
            proxy_pass      http://clisterb;

            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_cache     main;
            proxy_cache_valid       200 5m;
            proxy_cache_valid       302 1m;
        }

        location / {
            proxy_pass http://clusterb;

            proxy_set_header        Host             $host;
            proxy_set_header        X-Real-IP        $remote_addr;
            proxy_set_header        X-Forwarded-For  $proxy_add_x_forwarded_for;
        }

    }
}

答案1

server_name _ 不是默认名称服务器。它的字面意思是匹配主机名“_”。显然,这个主机名无效,所以你永远不会看到它,因此你的服务器块永远不会被使用。

如果你想创建一个 catch-all 服务器块,那么你应该使用 default_server(0.8.21 之前的默认设置)倾听指令

网上很多指南之所以误导您相信这一点,是因为他们总是将其放在第一位,如果没有提供默认服务器块,Nginx 就会回退到默认服务器块,然后他们会做出合乎逻辑的推断,因为其他人都这么说,所以它一定是真的。

当然,阅读官方文档或者server_name wiki 条目会立即启发你。

相关内容