虛擬伺服器名(
server name)是通過指令server_name來指定的。在
《 nginx是如何處理request的?》一節中,我們講到nginx分兩步來匹配過來的request請求:
1.選擇server
2.選擇location
在第1步中,其實也分兩步:
1).匹配port
2).匹配server_name
這一節就來聊聊nginx是如何具體匹配server_name的。
server_name指令
server_name的形式有三種:
1.精確網域名稱形式(exact names)
2.萬用字元(*)形式
3.正規表示式形式
如下:server
server
server
server
萬用字元形式,其實又分為前向萬用字元和後向萬用字元(分別如第二,第三個例子),萬用字元不能位於字串的中間位置。
當然,完全存在這麼一種情況,乙個host同時匹配上面三種的一種或者多種形式,比如host 為www.example.com可以同時匹配;
server_name
*.example.com *.com
www.example.com
www.example.* www.* ~^(.+)\.example\.com$
server_name
有6個指令引數,www.example.com都是
匹配的,那麼最後選擇哪乙個呢?
有一定的順序:
精確網域名稱匹配,
www.example.com
以萬用字元*開始的,最長的那個網域名稱,*.example.com
以萬用字元*結束的,最長的那個網域名稱,www.example.*
最後是正規表示式形式的,按照在配置檔案中出現的順序,依次嘗試進行匹配,選取第乙個被匹配到的網域名稱,~^(.+)\.example\.com$
精確網域名稱形式非常簡單,接下來分別對
server_name的萬用字元和正規表示式兩種形式做個介紹。
萬用字元
萬用字元*在server name中的使用非常嚴格:只能位於網域名稱的頭部或者尾部,不能出現在中間;並且必須以"."分隔開:
*.example.com
www.example.*
以下都是不合法的形式:
www.*.example.org
w*.example.org
當然,如果要達到後兩者所體現的目的,可以使用正規表示式,例如,上面不合法的兩個網域名稱可以寫成這樣:
~^www\..+\.example\.org$
~^w.*\.example\.org$
另外一種特殊的形式可以同時匹配example.org和*.example.org,這就是
.example.org
正規表示式
nginx的正規表示式語法使用的是perl語言(pcre)的正則語法。基本形式為
server_name ~^www\d+\.example\.net$;
這則表示式需要注意的幾點
例如:server_name "~^(?\w\d+)\.example\.net$";
如果不加引號,nginx便無法正確載入配置檔案,並報乙個錯誤:
directive "server_name" is not terminated by ";" in ...
正規表示式使用命名捕獲組,例如:
server
pcre語法支援下面幾種捕獲語法: ?
?'name' ?p
前面兩者是最新的語法,第三種是老的寫法。如果nginx報下面錯誤:
pcre_compile() failed: unrecognized character after (?< in ...
說明,你應該將
?或者?'name'改為較古老的?p寫法了。
同樣,使用普通捕獲組也是可以的:
server
當然,普通捕獲組要慎用,因為很容易被後面的正則所覆蓋。
其他形式
除了兩面提到的幾種形式,sername_name的指令引數還有可能是其他的幾種形式。
如果請求request沒有host的頭部,那麼如果想要匹配,可以用空字串:
server
另外,如果在server上下文中,沒有定義 server_name,那麼nginx使用空字串作為虛擬機器名稱。
如果使用ip而不是網域名稱來發起請求,那麼host請求頭就是乙個ip,此時server_name也可以寫成乙個ip:
server
"_"可以用來匹配所有的網域名稱
server
其他的字元,"-"和"!@#"也是可以的。
注意,匹配所有網域名稱的不能是"*"。
最佳實踐
我們知道nginx是乙個款高效能的web伺服器,其設計充滿了許多優化的技巧。在使用的時候也不例外,如果我們能對nginx的設計原理有一些了解,我們在配置時就能很好的利用這些設計,從而使得nginx的效率達到最大化。
前面提到,server_name的指令引數匹配有一定的匹配順序,即最先匹配
精確網域名稱形式,然後匹配以萬用字元*開始的網域名稱,其次匹配以萬用字元*結束的網域名稱,最後是匹配正則形式。如果前面匹配到了,就會終止繼續匹配。
從原理上說,這是因為,nginx會為每個監聽的port分別維護精確網域名稱,前向萬用字元和後項萬用字元的hash表。hash錶能在nginx啟動的配置階段得到建立和優化。精確網域名稱的hash表首先被搜尋,如果找不到,前向通配hash表會被接著被搜尋,如果也沒有找到,那麼後向通配hash表會被搜尋。搜尋通配hash表要比精確網域名稱hash表要慢,因為其是按照網域名稱的部分來做搜尋的(比如,*.example.com,會搜尋example和com部分)。
值得注意的是:".example.org"被存在通配hash表裡面,並沒有存在精確hash表裡面,因此匹配它是較慢的。
如果以上兩種方式都還沒有匹配上,那麼最後輪到正則形式的指令上場了。正則形式的網域名稱是按照先後順序乙個乙個的去匹配的,沒有存入任何hash表,匹配到正確的就結束,因此,這是最慢的形式,沒有任何「技巧」可言。
因此,最好的配置方式就是,
盡可能使用精確網域名稱,其次是萬用字元形式的,最後是正則形式。即便是正則形式網域名稱,也要根據實際需要將用的最多的網域名稱盡量前置
。這樣方可使得nginx的效能達到最大化。
例如:server
這種方式要優於:
server
長網域名稱,多網域名稱的情況
在某些情況下,網域名稱會非常的長,nginx不會允許其無限長,預設最大為32。在http上下文中,你可以通過server_names_hash_bucket_size指令來設定,可選引數有32,64(2的n次方)等
例如,如果網域名稱被定義為:"too.long.server.name.example.org",超過32字元,那麼會報錯:
could not build the server_names_hash,
you should increase server_names_hash_bucket_size: 32
解決方式:
在另一些情況下,server_name配置的網域名稱又很多,nginx同樣可能報錯:
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_names_hash_bucket_size的值(例如將2^n調整到2^(n+1))
如果乙個網域名稱是某個監聽埠下的唯一網域名稱,那麼nginx就不會建立hash匹配表,也不會有上面介紹的那些匹配流程,然而,如果這個唯一的網域名稱是乙個捕獲組正規表示式,那麼nginx還是去嘗試去解析正規表示式以提取這個字段。
Nginx的虛擬伺服器配置詳情
任何由server開始的部分都被稱作虛擬伺服器部分。它描述的是一組根據server name指令邏輯分割的資源,這些虛擬伺服器響應http請求,因此他們都包含在http部分之中。乙個虛擬伺服器由listen和server name指令組合定義,listen指令定乙個ip位址 埠組合或者是unix域套...
nginx 一台nginx伺服器多網域名稱配置
注意 使用正則的時候,一定要注意那個 線符號,這個是nginx識別正則的標準格式 nginx強大的正規表示式支援,可以使server name的配置變得很靈活,如果你要做多使用者部落格,那麼每個使用者擁有自己的二級網域名稱也就很容易實現了。下面說說server name的使用吧 server nam...
nginx 網域名稱配置 買了伺服器之後如何配置官網?
以阿里雲為例,購買了阿里雲伺服器後,通過遠端連線進入到伺服器。我使用的伺服器系統是centos 一 遠端配置命令進入伺服器,命令如下 ssh o gssapiauthentication no root xx.xx.xx.xx p22 預設22 按enter後輸入密碼。不記得可以在阿里雲重置。二 先...