一, 基於名稱的虛擬伺服器nginx首先確定哪個伺服器應處理該請求。讓我們從一個簡單的配置開始,其中所有三個虛擬伺服器都在埠*:80上偵聽: server { listen 80; server_name example.org www.example.org; ... } server { li ...
一, 基於名稱的虛擬伺服器
nginx首先確定哪個伺服器應處理該請求。讓我們從一個簡單的配置開始,其中所有三個虛擬伺服器都在埠*:80上偵聽:
server {
listen 80;
server_name example.org www.example.org;
...
}
server {
listen 80;
server_name example.net www.example.net;
...
}
server {
listen 80;
server_name example.com www.example.com;
...
}
在此配置中,nginx僅測試請求的header欄位“host”以確定應將請求路由到哪個伺服器。如果其值與任何伺服器名稱都不匹配,或者請求根本不包含此header欄位,則nginx會將請求路由到該埠的預設伺服器。在上面的配置中,預設伺服器是第一個伺服器-這是nginx的標準預設行為。還可以使用listen指令中的default_server參數來顯式設置哪個伺服器應為預設伺服器:
server {
listen 80 default_server;
server_name example.net www.example.net;
...
}
自0.8.21版以後的版本,default_server參數已可用。在早期版本中,應改用預設參數。
請註意,預設伺服器是偵聽埠的屬性,而不是伺服器名稱的屬性。稍後再詳細介紹。
二, 如何阻止使用未定義的伺服器名稱的http請求
如果不允許不帶“主機”header欄位的請求,則可以定義僅丟棄請求的伺服器:
server {
listen 80
server_name ””;
return 444;
}
在這裡,伺服器名稱設置為空字元串,該字元串將與沒有“ Host”header欄位的請求進行匹配,並返回特殊的nginx的非標準代碼444,以關閉連接。
從版本0.8.48開始,這是伺服器名稱的預設設置,因此可以省略server_name“”。在早期版本中,電腦的主機名用作預設伺服器名。
三, 基於名稱和IP地址混合的虛擬伺服器
讓我們看一個更複雜的配置,其中一些虛擬伺服器偵聽不同的地址:
server {
listen 192.168.1.1:80;
server_name example.org www.example.org;
...
}
server {
listen 192.168.1.1:80;
server_name example.net www.example.net;
...
}
server {
listen 192.168.1.2:80;
server_name example.com www.example.com;
...
}
在這種配置中,nginx首先根據伺服器塊的偵聽指令測試請求的IP地址和埠。然後,它根據與IP地址和埠匹配的伺服器塊的server_name條目測試請求的“主機”header欄位。如果找不到伺服器名稱,則預設伺服器將處理該請求。例如,在192.168.1.1:80埠上收到的對www.example.com的請求將由192.168.1.1:80埠的預設伺服器(即第一臺伺服器)處理,因為沒有www.example.com為此埠定義。
如前所述,預設伺服器是偵聽埠的屬性,並且可以為不同的埠定義不同的預設伺服器:
server {
listen 192.168.1.1:80;
server_name example.org www.example.org;
...
}
server {
listen 192.168.1.1:80 default_server;
server_name example.net www.example.net;
...
}
server {
listen 192.168.1.2:80 default_server;
server_name example.com www.example.com;
...
}
四, 一個簡單的PHP站點配置
現在,讓我們看看nginx如何選擇一個位置來處理典型的簡單PHP網站的請求:
server {
listen 80
server_name example.org www.example.org;
root /data/www;
location / {
index index.html index.php;
}
location ~* \。(gif | jpg | png)$ {
expires 30d;
}
location ~\ .php $ {
fastcgi_pass localhost:9000;
fastcgi_param SCRIPT_FILENAME
$ document_root $ fastcgi_script_name;
include fastcgi_params;
}
}
無論列出的順序如何,nginx首先搜索文字字元串給定的最特定的首碼位置。在上面的配置中,唯一的首碼位置是“/”,並且由於它匹配任何請求,因此將被用作最後的手段。然後,nginx按照配置文件中列出的順序檢查由正則表達式指定的位置。第一個匹配的表達式將停止搜索,nginx將使用此位置。如果沒有正則表達式與請求匹配,則nginx使用較早發現的最特定的首碼位置。
請註意,所有類型的位置僅測試沒有參數的請求行的URI部分。這樣做是因為查詢字元串中的參數可以通過幾種方式給出,例如:
/index.php?user=john&page=1
/index.php?page=1&user=john
此外,任何人都可以在查詢字元串中請求任何內容:
/index.php?page=1&something+else&user=john
現在,讓我們看一下在以上配置中如何處理請求:
請求“/logo.gif”, 首先與首碼位置“/”匹配,然後與正則表達式“\.(gif | jpg | png)$”匹配,因此由後一個位置處理。使用指令“root /data/www”將請求映射到文件/data/www/logo.gif,然後將文件發送給客戶端。
請求“/index.php”, 也首先與首碼位置“/”匹配,然後與正則表達式“\.(php)$”匹配。因此,它由後一個位置處理,並將請求傳遞到在localhost:9000上偵聽的FastCGI伺服器。 fastcgi_param指令將FastCGI參數SCRIPT_FILENAME設置為“ /data/www/index.php”,然後FastCGI伺服器執行該文件。變數$document_root等於root指令的值,變數$fastcgi_script_name等於請求URI,即“/index.php”。
請求“/about.html”僅與首碼位置“/”匹配,因此在該位置進行處理。使用指令“root /data/www”將請求映射到文件/data/www/about.html,然後將文件發送給客戶端。
處理請求“/”更為複雜。它僅與首碼位置“/”匹配,因此由該位置處理。然後,index指令根據其參數和“root /data/www”指令對索引文件的存在進行測試。如果文件/data/www/index.html不存在,文件/data/www/index.php存在,則該指令將內部重定向到“/index.php”,並且nginx再次搜索位置如果請求是由客戶端發送的。如前所述,重定向的請求最終將由FastCGI伺服器處理。