nginx Server names


通配符名稱

正則表達式名稱

混合名稱

優化

兼容性

server名稱定義使用的server_name指令和決定哪個server塊用於一個給定的請求。

參見“怎樣Nginx處理一個請求”。能夠使用確切名稱、通配符或正則表達式定義它們:

server {
    listen       80;
    server_name  example.org  www.example.org;
    ...
}

server {
    listen       80;
    server_name  *.example.org;
    ...
}

server {
    listen       80;
    server_name  mail.*;
    ...
}

server {
    listen       80;
    server_name  ~^(?<user>.+)\.example\.net$;
    ...
}



當通過名稱搜索虛擬server時,假設名稱與指定的變體(比如通配符名稱和正則表達式匹配)中的一個匹配。則將依照下列順序選擇第一匹配變體:

1.確切的名字

2.最長通配符名稱以星號開始,比如“*.abc.com

3.最長通配符名稱以星號結尾,比如“mail.*”

4.第一匹配的正則表達式(以配置文件的外觀順序)


通配符的名字通配符名稱可能僅僅包括在名稱的開始或結束。僅僅有在點邊界。名稱為“。比如。

org”和“W *演示樣例。org”無效。然而,這些名稱能夠使用正則表達式來指定。比如,“\\ WWW \ + \實例$ \ $”和“。星號能夠匹配幾個名稱部分。“*。樣例。org”比賽不僅www.example.org但www.sub.example.org以及。表單中的一個特殊通配符名稱能夠用來匹配准確的名稱“演示樣例”和通配符名稱。


通配符

一個通配符可能僅僅在名稱的開始或者結束包涵一個*。僅僅在一個邊界。

名稱 “www.*.example.org” 和 “w*.example.org” 是無效的. 然而這些名稱能夠使用正則表達式, 比如, “~^www\..+\.example\.org$”或者“~^w.*\.example\.org$”. * 號能夠匹配部分名稱。 名稱 “*.example.org” 不僅能夠匹配 www.example.org 也能夠匹配www.sub.example.org.

表單中的特殊通配符名稱“.example.org” 可用於匹配的確切名稱 “example.org” 和通配符名稱“*.example.org”.

正則表達式主機名


nginx 使用的正則表達式與 Perl 語言的正則表達式(PCRE)兼容。使用正則表達式主機名,server name 必須以 “~” 字符為起始字符。

server_name  ~^www\d+\.example\.net$;

假設不以 “~” 字符為起始字符,該 server name 將被視為 “准確的主機名” 或者當 server name 包括 “*” 時被視為 “通配主機名” (多數情況是非法通配主機名。由於僅僅有當 “*” 在 server name 的起始或結尾時才合法)。

不要忘記設置 “^” 和 “$” 錨定符對主機名進行界定。這不是 nginx 的配置語法要求。而是為了使正則表達式能正確匹配。

同一時候也要注意,域名的分隔符 “.” 在正則表達式中應該以 “\” 引用。假設在正則表達式中使用了 “{” 和 “}” 字符。應該將整個正則表達式引用起來。由於花括弧在 nginx 配置中也有特殊意義,引用起來以避免被 nginx 錯誤解析。比如:

server_name  "~^(?<name>\w\d{1,3}+)\.example\.net$";

假設不引用起來,nginx 會啟動失敗,並顯演示樣例如以下錯誤信息:

directive "server_name" is not terminated by ";" in ...

正則表達式的 named capture (使用一個名字對匹配的字符串進行引用)可被視為一個變量,在后面的配置中使用:

server {
    server_name   ~^(www\.)?

(?<domain>.+)$; location / { root /sites/$domain; } }

PCRE 庫支持 named capture。有例如以下幾種語法:

?<name>        Perl 5.10 compatible syntax, supported since PCRE-7.0
?'name'        Perl 5.10 compatible syntax, supported since PCRE-7.0
?

P<name> Python compatible syntax, supported since PCRE-4.0

可參考:pcre2pattern

 \d     any decimal digit
 \D     any character that is not a decimal digit
 \h     any horizontal white space character
 \H     any character that is not a horizontal white space character
 \s     any white space character
 \S     any character that is not a white space character
 \v     any vertical white space character
 \V     any character that is not a vertical white space character
 \w     any "word" character
 \W     any "non-word" character

假設 nginx 啟動失敗,並顯演示樣例如以下信息:

pcre_compile() failed: unrecognized character after (?< in ...

這表示 PCRE 庫太老舊。可嘗試使用 “?P<name>” 替代 “?<name>”。

named capture 也能以數字形式使用:

server {
    server_name   ~^(www\.)?

(.+)$; location / { root /sites/$2; } }

不管怎樣。數字形式的使用應盡量簡單,由於數字是僅僅是順序標識,而不是被匹配的字符串的標識。這導致數字引用非常easy被覆蓋。

混雜主機名


有一些主機名是被特殊對待的。

對於沒有定義 “Host” 請求首部的請求。假設希望在某個 server 區塊中處理這種請求,應在 server_name 指令的參數中加入 "" 空字符串參數:

server {
    listen       80;
    server_name  example.org  www.example.org  "";
    ...
}

在《nginx 是怎樣處理訪問請求的》一文中以前介紹過,假設 server 區塊中未定義 server_name 指令,便如同定義了 server_name ""。

Note:
在 0.8.48 版曾經,遇到 server 區塊中未定義 server_name 指令的情況,
會將系統的主機名設置為 server 區塊的 server name,而不是自己主動設置 ""server name。

在 0.9.4 版本號,假設設置:server_name $hostname,會將系統的主機名設置為 server name。

假設某個訪問使用了 IP 地址 而不是 server name,“Host” 請求首部會包括 IP 地址。對於這種請求,可使用例如以下的配置:

server {
    listen       80;
    server_name  example.org
                 www.example.org
                 ""
                 192.168.1.1
                 ;
    ...
}

以下是一個 catch-all server 區塊的配置。使用了 “_” 作為 server name:

server {
    listen       80  default_server;
    server_name  _;
    return       444;
}

這個 server name 並沒有什么特殊之處。它僅是一個無效的域名而已。也能夠使用其它類似的名字。如 “--” and “!@#” 。

0.6.25 版以前的 nginx 以前支持一個特殊的 server name: “*”。這個特殊主機名被錯誤的解釋成一個 catch-all 主機名。但它從未以一個 catch-all 或者 通配主機名工作。它的功能實際上與如今的 server_name_in_redirect 指令的功能同樣:server_name_in_redirect

特殊的 server name “*” 如今已經被棄用,應使用 server_name_in_redirect 指令。

要注意的是。使用 server_name 指令無法指定 defalt server 或是 catch-all name,這是 listen 指令的屬性,不是 server_name 指令的屬性。

可參考《nginx 是怎樣處理訪問請求的》。

我們能夠定義兩個 server,它們都同一時候監聽於 *:80 port 和 *:8080 port。將當中一個設置為 *:80 port的默認 server,將還有一個設置為 *:8080 port的默認 server:

server {
    listen       80;
    listen       8080  default_server;
    server_name  example.net;
    ...
}

server {
    listen       80  default_server;
    listen       8080;
    server_name  example.org;
    ...
}

對主機名的優化


准確的主機名、以 “*” 起始的通配主機名、以 “*” 結尾的通配主機名,這三種主機名被存放在三個 hash table 中。這三個 hash table 是與監聽port綁定的。

hash table 的大小在配置階段被優化。優化的目的是努力減少這些名字在 CPU 緩存中命中失敗的幾率。關於設置 hash table 的具體討論請參考:hash

在匹配主機名時,首先查找“准確主機名”的 hash table,假設沒有找到。會查找以 “*” 起始的“通配主機名”的 hash table,假設沒有仍未找到。會查找以 “*” 結尾的“通配主機名”的 hash table。

對於“通配主機名”的 hash table 的檢索會更慢,由於是以主機名的域名部分去檢索的。

注意,對於特殊的通配主機名,形如 “.example.org”,這種主機名是存放在“通配主機名”的 hash table 中,而不是存放在“准確主機名”的 hash table 中。

假設前面都未找到。正則表達式會按寫在配置文件里的順序被測試,因此正則表達式是最慢的方法。而且沒有可擴展性。

由於以上這些原因。在可能的情況下最好使用 “准確的主機名”。比如。假設對於 example.org 和 www.example.org 的請求最為頻繁,對他們進行顯式的定義會更有效率:

server {
    listen       80;
    server_name  example.org  www.example.org  *.example.org;     ...
}

以下的定義方法不如上面的配置有效率:

server {
    listen       80;
    server_name  .example.org;
    ...
}

假設定義了大量的主機名,或者使用了非常長的主機名。應在配置文件的 http context 中調整這個兩個參數:

server_names_hash_bucket_size 指令的默認值可能為 32 或 64 或 其它數字。這是依據 CPU 緩存線大小而定的。

假設默認值為 32。並且定義了一個 server name 為:“too.long.server.name.example.org” 這時 nginx 就不能啟動。並且顯演示樣例如以下的錯誤信息:

could not build the server_names_hash,
you should increase server_names_hash_bucket_size: 32

遇到這樣的情況,應將默認值設置為原來的兩倍:

http {
    server_names_hash_bucket_size  64;
    ...

假設定義了大量的主機名。可能顯演示樣例如以下的錯誤信息:

could not build the server_names_hash,
you should increase either server_names_hash_max_size: 512
or server_names_hash_bucket_size: 32

遇到這樣的情況,首先嘗試調整 server_names_hash_max_size 的值。設置為大於 server name 總數的值。

假設這樣設置仍不能讓 nginx 正常啟動。或者 nginx 啟動的時間變得過長,再嘗試添加 server_names_hash_bucket_size 的值。

假設一個 server 是某個監聽port唯一的 server,這時 nginx 根本不會去測試 server name。同一時候也不會為該監聽port構建 hash table。

但當中又有一個例外,假設 server name 是正則表達式,並且正則表達式中包括了 captures,這時 nginx 不得不運行該正則表達式以獲取 captures。

(正則表達式的 capture 是指被圓括號引用的表達式部分。它們所匹配的字符串,可通過名字或數字引用)

兼容性


從 0.9.4 開始支持特殊主機名 “$hostname”

從 0.8.48 開始,假設 server 區塊中沒有定義 server_name 指令,nginx 默認設定空字符串為主機名,如同定義了 server_name ""

從 0.8.25 開始支持在“正則表達式主機名”中使用 named capture 特性

從 0.7.40 開始支持在“正則表達式主機名”中使用 capture 特性

從 0.7.12 開始支持 "" 空字符串主機名

從 0.6.25 開始,支持使用“正則表達式主機名”或者“通配主機名”作為第一個主機名。

從 0.6.7 開始支持“正則表達式主機名”

從 0.6.0 開始支持形如 example.* 的“通配主機名”

從 0.3.18 開始支持形如 .example.org 的特殊“通配主機名”

從 0.1.13 開始支持形如 *.example.org 的“通配主機名”




翻譯:http://nginx.org/en/docs/http/server_names.html



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM