Nginx的虛擬伺服器網域名稱配置

2021-08-14 16:20:01 字數 4444 閱讀 9585

虛擬伺服器名(

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後輸入密碼。不記得可以在阿里雲重置。二 先...