通配符名稱
正則表達式名稱
混合名稱
優化
兼容性
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