Nginx Practice in Windows - 4 server names

Description

    server {
        listen       127.0.0.1:8080;
        server_name  server1;
        location /test {
            return 200 'server1';
        }
    } 
在這個 server 設定中, server_name 是拿來比對 request header "HOST" 然後決定交由哪個 server 提供服務.
這個 server_name 除了能服務完全相同的 HOST 以外還支援 * (wildcard) 跟 regular expression

Reference

Practice

如果與 HOST 完全一樣, 就取 HOST 完全一樣的 server.

  1. setup nginx.conf (這裡 ~開頭就表示要用 regular expression)
        server {
            listen       127.0.0.1:8080 default;
            server_name  *.server1;
            location /test {
                return 200 '*.server1';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  server1;
            location /test {
                return 200 'server1';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  www.*;
            location /test {
                return 200 'www.*';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  ~.*server1.*;
            location /test {
                return 200 '~.*server1.*';
            }
        } 
    
  2. run "nginx -s reload"
  3. run "telnet 127.0.0.1 8080"
  4. send request
    GET /test HTTP/1.1
    Host: server1:8080
    Connection: close
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
    Accept: */*
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4
    
  5. get response
    HTTP/1.1 200 OK
    Server: nginx/1.4.3
    Date: Wed, 23 Oct 2013 22:36:16 GMT
    Content-Type: application/octet-stream
    Content-Length: 7
    Connection: close
    
    server1
    

一個 server_name 不能指定兩個 *

  1. setup nginx.conf
        server {
            listen       127.0.0.1:8080;
            server_name  *.server1.*;
            location /test {
                return 200 '*.server1';
            }
        } 
    
  2. run "nginx -s reload"
  3. got error message
    nginx: [emerg] invalid server name or wildcard "*.server1.*" on 127.0.0.1:8080
    

當 * 開頭跟 * 結尾的兩個 server_name 都 mapping 到一個 request 時, 用 * 開頭的 server 服務

  1. setup nginx.conf
        server {
            listen       127.0.0.1:8080;
            server_name  *.server1;
            location /test {
                return 200 '*.server1';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  www.*;
            location /test {
                return 200 'server1.*';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  server1;
            location /test {
                return 200 'server1';
            }
        } 
        server {
            listen       127.0.0.1:8080 default;
            server_name  ~.*server1.*;
            location /test {
                return 200 '~.*server1.*';
            }
        } 
    
  2. run "nginx -s reload"
  3. run "telnet 127.0.0.1 8080"
  4. send request
    GET /test HTTP/1.1
    Host: www.server1
    Connection: close
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
    Accept: */*
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4
    
  5. get response
    HTTP/1.1 200 OK
    Server: nginx/1.4.3
    Date: Wed, 23 Oct 2013 22:58:48 GMT
    Content-Type: application/octet-stream
    Content-Length: 9
    Connection: close
    
    *.server1
    
  6. run "telnet 127.0.0.1 8080"
  7. send request (這個 request 的 Host 比較長, 但 nginx 仍可以判斷)
    GET /test HTTP/1.1
    Host: www.abc.qqq.hahaha.server1
    Connection: close
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
    Accept: */*
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4
    
  8. get response
    HTTP/1.1 200 OK
    Server: nginx/1.4.3
    Date: Wed, 23 Oct 2013 22:58:48 GMT
    Content-Type: application/octet-stream
    Content-Length: 9
    Connection: close
    
    *.server1

如果 mapping 到的 * 開頭的 server 不止一個, 就取 mapping 到最長的 server

  1. setup nginx.conf
        server {
            listen       127.0.0.1:8080;
            server_name  *.server1;
            location /test {
                return 200 '*.server1';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  *.hahaha.server1;
            location /test {
                return 200 '*.hahaha.server1';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  www.*;
            location /test {
                return 200 'www.*';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  server1;
            location /test {
                return 200 'server1';
            }
        } 
        server {
            listen       127.0.0.1:8080 default;
            server_name  ~.*server1.*;
            location /test {
                return 200 '~.*server1.*';
            }
        } 
    
  2. run "nginx -s reload"
  3. run "telnet 127.0.0.1 8080"
  4. send request
    GET /test HTTP/1.1
    Host: www.abc.qqq.hahaha.server1
    Connection: close
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
    Accept: */*
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4
    
    
  5. get response
    HTTP/1.1 200 OK
    Server: nginx/1.4.3
    Date: Wed, 23 Oct 2013 23:07:06 GMT
    Content-Type: application/octet-stream
    Content-Length: 16
    Connection: close
    
    *.hahaha.server1

如果對應不到 * 開頭的 server_name, 就找 mapping 到最長的以 * 結尾的 server_name

  1. setup nginx.conf
        server {
            listen       127.0.0.1:8080;
            server_name  *.server1;
            location /test {
                return 200 '*.server1';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  *.hahaha.server1;
            location /test {
                return 200 '*.hahaha.server1';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  www.*;
            location /test {
                return 200 'www.*';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  www.abc.qqq.*;
            location /test {
                return 200 'www.abc.qqq.*';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  server1;
            location /test {
                return 200 'server1';
            }
        } 
        server {
            listen       127.0.0.1:8080 default;
            server_name  ~.*server1.*;
            location /test {
                return 200 '~.*server1.*';
            }
        } 
    
  2. run "nginx -s reload"
  3. run "telnet 127.0.0.1 8080"
  4. send request
    GET /test HTTP/1.1
    Host: www.abc.qqq.hahaha.server1.net
    Connection: close
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
    Accept: */*
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4
    
    
  5. get response
    HTTP/1.1 200 OK
    Server: nginx/1.4.3
    Date: Wed, 23 Oct 2013 23:13:59 GMT
    Content-Type: application/octet-stream
    Content-Length: 13
    Connection: close
    
    www.abc.qqq.*

"*" 只能出現在 server_name 的開頭或結尾, 不能放中間

  1. setup nginx.conf
        server {
            listen       127.0.0.1:8080;
            server_name  *.server1.*;
            location /test {
                return 200 '*.server1.*';
            }
        } 
    
  2. run "nginx -s reload"
  3. got error message
    nginx: [emerg] invalid server name or wildcard "*.server1.*" on 127.0.0.1:8080

如果 * 也都對應不到 server_name, 就用 regular expression (~ 開頭) 找第一個對應到的 server_name

  1. setup nginx.conf
        server {
            listen       127.0.0.1:8080;
            server_name  *.server1;
            location /test {
                return 200 '*.server1';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  *.hahaha.server1;
            location /test {
                return 200 '*.hahaha.server1';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  www.*;
            location /test {
                return 200 'www.*';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  www.abc.qqq.*;
            location /test {
                return 200 'www.abc.qqq.*';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  server1;
            location /test {
                return 200 'server1';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  ~.*server1.*;
            location /test {
                return 200 '~.*server1.*';
            }
        } 
        server {
            listen       127.0.0.1:8080 default;
            server_name  ~.*abc\.qqq\.hahaha\.server1.*;
            location /test {
                return 200 '~.*abc\.qqq\.hahaha\.server1.*';
            }
        } 
    
  2. run "nginx -s reload"
  3. run "telnet 127.0.0.1 8080"
  4. send request
    GET /test HTTP/1.1
    Host: xyz.abc.qqq.hahaha.server1.net
    Connection: close
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
    Accept: */*
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4
    
    
  5. get response
    HTTP/1.1 200 OK
    Server: nginx/1.4.3
    Date: Wed, 23 Oct 2013 23:37:15 GMT
    Content-Type: application/octet-stream
    Content-Length: 13
    Connection: close
    
    ~.*server1.*
  6. setup nginx.conf
        server {
            listen       127.0.0.1:8080;
            server_name  *.server1;
            location /test {
                return 200 '*.server1';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  *.hahaha.server1;
            location /test {
                return 200 '*.hahaha.server1';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  www.*;
            location /test {
                return 200 'www.*';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  www.abc.qqq.*;
            location /test {
                return 200 'www.abc.qqq.*';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  server1;
            location /test {
                return 200 'server1';
            }
        } 
        server {
            listen       127.0.0.1:8080 default;
            server_name  ~.*abc\.qqq\.hahaha\.server1.*;
            location /test {
                return 200 '~.*abc\.qqq\.hahaha\.server1.*';
            }
        } 
    
        server {
            listen       127.0.0.1:8080;
            server_name  ~.*server1.*;
            location /test {
                return 200 '~.*server1.*';
            }
        } 
  7. run "nginx -s reload"
  8. run "telnet 127.0.0.1 8080"
  9. send request
    GET /test HTTP/1.1
    Host: xyz.abc.qqq.hahaha.server1.net
    Connection: close
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
    Accept: */*
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4
    
    
  10. get response
    HTTP/1.1 200 OK
    Server: nginx/1.4.3
    Date: Wed, 23 Oct 2013 23:39:05 GMT
    Content-Type: application/octet-stream
    Content-Length: 31
    Connection: close
    
    ~.*abc\.qqq\.hahaha\.server1.*

如果 server_name 的 regular expression 包含 "{" 跟 "}", 就必須用 "" 把 regular expression 包起來, 否則 nginx 會報錯

  1. setup nginx.conf
        server {
            listen       127.0.0.1:8080 default;
            server_name  ~.*abc\.q{3}\.hahaha\.server1.*;
            location /test {
                return 200 '~.*abc\.q{3}\.hahaha\.server1.*';
            }
        }
     
  2. run "nginx -s reload"
  3. get error message
    nginx: [emerg] directive "server_name" is not terminated by ";" in C:\Users\isaac\Downloads\nginx-1.4.3\nginx-1.4.3/conf/nginx.conf:72
    
  4. setup nginx.conf
        server {
            listen       127.0.0.1:8080;
            server_name  *.server1;
            location /test {
                return 200 '*.server1';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  *.hahaha.server1;
            location /test {
                return 200 '*.hahaha.server1';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  www.*;
            location /test {
                return 200 'www.*';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  www.abc.qqq.*;
            location /test {
                return 200 'www.abc.qqq.*';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  server1;
            location /test {
                return 200 'server1';
            }
        } 
        server {
            listen       127.0.0.1:8080 default;
            server_name  "~.*abc\.q{3}\.hahaha\.server1.*";
            location /test {
                return 200 '~.*abc\.q{3}\.hahaha\.server1.*';
            }
        } 
        server {
            listen       127.0.0.1:8080;
            server_name  ~.*server1.*;
            location /test {
                return 200 '~.*server1.*';
            }
        }
     
  5. run "nginx -s reload"
  6. run "telnet 127.0.0.1 8080"
  7. send request
    GET /test HTTP/1.1
    Host: xyz.abc.qqq.hahaha.server1.net
    Connection: close
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
    Accept: */*
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4
    
    
  8. get response
    HTTP/1.1 200 OK
    Server: nginx/1.4.3
    Date: Wed, 23 Oct 2013 23:51:10 GMT
    Content-Type: application/octet-stream
    Content-Length: 31
    Connection: close
    
    ~.*abc\.q{3}\.hahaha\.server1.*

在 server_name 可用 regular expression 替 mapping 到的值命名成變數以便在之後使用

  1. setup nginx.conf
        server {
            listen       127.0.0.1:8080;
            server_name  ~(?P.*)\.server1.*;
            location /test {
                return 200 'you request ${serviceName} service, service_name pattern ~(?P.*)\.server1.* is Python compatible syntax, supported since PCRE-4.0';
            }
        } 
        server {
            listen       127.0.0.1:8081;
            server_name  ~(?.*)\.server1.*;
            location /test {
                return 200 'you request ${serviceName} service, service_name pattern ~(?.*)\.server1.* is Perl 5.10 compatible syntax, supported since PCRE-7.0';
            }
        } 
    
  2. run "nginx -s reload"
  3. run "telnet 127.0.0.1 8080"
  4. send request
    GET /test HTTP/1.1
    Host: tw.mail.server1.net
    Connection: close
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
    Accept: */*
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4
    
  5. get response
    HTTP/1.1 200 OK
    Server: nginx/1.4.3
    Date: Sun, 27 Oct 2013 05:14:53 GMT
    Content-Type: application/octet-stream
    Content-Length: 135
    Connection: close
    
    you request tw.mail service, service_name pattern ~(?P.*)\.server1.* is Python compatible syntax, supported since PCRE-4.0
    
  6. run "telnet 127.0.0.1 8081"
  7. send request
    GET /test HTTP/1.1
    Host: tw.mail.server1.net
    Connection: close
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
    Accept: */*
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4
    
  8. get response
    HTTP/1.1 200 OK
    Server: nginx/1.4.3
    Date: Sun, 27 Oct 2013 05:16:06 GMT
    Content-Type: application/octet-stream
    Content-Length: 137
    Connection: close
    
    you request tw.mail service, service_name pattern ~(?.*)\.server1.* is Perl 5.10 compatible syntax, supported since PCRE-7.0
    
    

在 server_name 透過 regular expression 將 mapping 到的值可在之後用數字編號當變數使用

  1. setup nginx.conf
        server {
            listen       127.0.0.1:8080;
            server_name  ~(.*)\.(.*);
            location /test {
                return 200 'you request service "$1" in domain "$2"';
            }
        } 
    
  2. run "nginx -s reload"
  3. run "telnet 127.0.0.1 8080"
  4. send request
    GET /test HTTP/1.1
    Host: mail.server1
    Connection: close
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
    Accept: */*
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4
    
  5. get response
    HTTP/1.1 200 OK
    Server: nginx/1.4.3
    Date: Sun, 27 Oct 2013 05:22:37 GMT
    Content-Type: application/octet-stream
    Content-Length: 46
    Connection: close
    
    you request service "mail" in domain "server1"
    

如果沒指定 server_name, nginx 就會用 hostname 作為 server_name

  1. setup nginx.conf
        server {
            listen       127.0.0.1:8080;
            location /test {
                return 200 'you request ${hostname}';
            }
        }  
    
  2. run "nginx -s reload"
  3. run "telnet 127.0.0.1 8080"
  4. send request
    GET /test HTTP/1.1
    Host: 127.0.0.1
    Connection: close
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
    Accept: */*
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4
    
  5. get response
    HTTP/1.1 200 OK
    Server: nginx/1.4.3
    Date: Sun, 27 Oct 2013 05:41:41 GMT
    Content-Type: application/octet-stream
    Content-Length: 20
    Connection: close
    
    you request isaac-pc

設定一個"全部"的 server_name

  1. setup nginx.conf
        server {
            listen       8080;
            server_name  _;
            location / {
                return 200 'you request ${http_Host}';
            }
        }
    
  2. run "nginx -s reload"
  3. run "telnet 127.0.0.1 8080"
  4. send request
    GET / HTTP/1.1
    Host: abc:8080
    Connection: close
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
    Accept: */*
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4
    
  5. get response
    HTTP/1.1 200 OK
    Server: nginx/1.4.3
    Date: Wed, 30 Oct 2013 23:39:30 GMT
    Content-Type: application/octet-stream
    Content-Length: 20
    Connection: close
    
    you request abc:8080
  6. setup nginx.conf
        server {
            listen       8080;
            server_name  --;
            location / {
                return 200 'you request ${http_Host}';
            }
        }  
  7. run "nginx -s reload"
  8. run "telnet 127.0.0.1 8080"
  9. send request
    GET / HTTP/1.1
    Host: abc:8080
    Connection: close
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
    Accept: */*
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4
    
  10. get response
    HTTP/1.1 200 OK
    Server: nginx/1.4.3
    Date: Wed, 30 Oct 2013 23:39:30 GMT
    Content-Type: application/octet-stream
    Content-Length: 20
    Connection: close
    
    you request abc:8080
  11. setup nginx.conf
  12.     server {
            listen       8080;
            server_name  !@#;
            location / {
                return 200 'you request ${http_Host}';
            }
        }  
  13. run "nginx -s reload"
  14. run "telnet 127.0.0.1 8080"
  15. send request
    GET / HTTP/1.1
    Host: abc:8080
    Connection: close
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
    Accept: */*
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4
    
  16. get response
    HTTP/1.1 200 OK
    Server: nginx/1.4.3
    Date: Wed, 30 Oct 2013 23:39:30 GMT
    Content-Type: application/octet-stream
    Content-Length: 20
    Connection: close
    
    you request abc:8080

沒有留言:

張貼留言

別名演算法 Alias Method

 題目 每個伺服器支援不同的 TPM (transaction per minute) 當 request 來的時候, 系統需要馬上根據 TPM 的能力隨機找到一個適合的 server. 雖然稱為 "隨機", 但還是需要有 TPM 作為權重. 解法 別名演算法...