Nginx配置與部署中文手冊(1)Nginx的請求處理 .
Nginx配置與部署中文手冊(1)Nginx的請求處理 .
英文原文:http://nginx.org/en/docs/http/request_processing.html
原文作者:Igor Sysoev
中文譯者:Poechant
特別聲明:
(1)本人提供意譯,不提供咬文嚼字的逐句翻譯。
(2)由於本人語言水平有限,部分辭彙無法找到合適的中文辭彙對應,所以仍然使用英文。另外關鍵詞等,不會翻譯成中文。
(3)本文歡迎傳播,但請註明出處。
(4)歡迎提各種寶貴建議。
1.處理什麼樣的請求
處理訪問到Nginx所在IP地址的請求,並且這些請求的HTTP頭信息中的Host為所要處理的域名(如下以80埠為例),如下幾個server就對應響應的請求:view plaincopy to clipboardprint?
01.server {
02. listen 80;
03. server_name nginx.org www.nginx.org;
04. ...
05.}
06.
07.server {
08. listen 80;
09. server_name nginx.net www.nginx.net;
10. ...
11.}
12.
13.server {
14. listen 80;
15. server_name nginx.com www.nginx.com;
16. ...
17.}
server {
listen 80;
server_name nginx.org www.nginx.org;
...
}
server {
listen 80;
server_name nginx.net www.nginx.net;
...
}
server {
listen 80;
server_name nginx.com www.nginx.com;
...
}2.默認server
如果不主動設置默認server,那麼第一個server就會被當做默認server。若要主動設置,應該如下配置:view plaincopy to clipboardprint?
01.server {
02. listen 80 default_server;
03. server_name nginx.net www.nginx.net;
04. ...
05.}
server {
listen 80 default_server;
server_name nginx.net www.nginx.net;
...
} 此項的版本注意事項:
0.8.21版本之前,使用default關鍵詞;
從0.8.21版本開始,使用default_server關鍵詞。
另外注意,default_server是埠的一個屬性,不是server_name的一個屬性。
3.如何處理未定義host為server_name的請求
比如,如果不想處理HTTP請求中沒有HOST欄位的頭信息的情況,那麼可以如下:view plaincopy to clipboardprint?
01.server {
02. listen 80;
03. server_name "";
04. return 444;
05.}
server {
listen 80;
server_name "";
return 444;
}此項的版本注意事項:
0.8.48之前的版本,如果沒有設置server_name的話,那麼會把server_name設置為本機的hostname。
0.8.48開始的版本,如果沒有設置server_name的話,那麼會把server_name設置為"",所以如果要達到上述代碼的效果,在此版本開始可以不設置server_name。
4.Nginx的虛擬主機監聽
請先看如下配置:view plaincopy to clipboardprint?
01.server {
02. listen 192.168.1.1:80;
03. server_name nginx.org www.nginx.org;
04. ...
05.}
06.
07.server {
08. listen 192.168.1.1:80;
09. server_name nginx.net www.nginx.net;
10. ...
11.}
12.
13.server {
14. listen 192.168.1.2:80;
15. server_name nginx.com www.nginx.com;
16. ...
17.}
server {
listen 192.168.1.1:80;
server_name nginx.org www.nginx.org;
...
}
server {
listen 192.168.1.1:80;
server_name nginx.net www.nginx.net;
...
}
server {
listen 192.168.1.2:80;
server_name nginx.com www.nginx.com;
...
}這個應該很好理解,如果listen的IP地址和埠號都吻合了,就看HTTP請求中的HOST頭信息與某個server_name中的name是否吻合。如果server_name不吻合,就到該埠對應的default_server那裡處理請求,如果default_server的server_name也沒有與HOST頭信息吻合,那麼就放棄該請求。
特別再次強調,default_server是埠的屬性,而非server_name的屬性。所以可以有如下配置:view plaincopy to clipboardprint?
01.server {
02. listen 192.168.1.1:80;
03. server_name nginx.org www.nginx.org;
04. ...
05.}
06.
07.server {
08. listen 192.168.1.1:80 default_server;
09. server_name nginx.net www.nginx.net;
10. ...
11.}
12.
13.server {
14. listen 192.168.1.2:80 default_server;
15. server_name nginx.com www.nginx.com;
16. ...
17.}
server {
listen 192.168.1.1:80;
server_name nginx.org www.nginx.org;
...
}
server {
listen 192.168.1.1:80 default_server;
server_name nginx.net www.nginx.net;
...
}
server {
listen 192.168.1.2:80 default_server;
server_name nginx.com www.nginx.com;
...
}5.一個簡單的PHP站點的Nginx配置view plaincopy to clipboardprint?
01.server {
02. listen 80;
03. server_name nginx.org www.nginx.org;
04. root /data/www;
05.
06. location / {
07. index index.html index.php;
08. }
09.
10. location ~* \.(gif|jpg|png)$ {
11. expires 30d;
12. }
13.
14. location ~ \.php$ {
15. fastcgi_pass localhost:9000;
16. fastcgi_param SCRIPT_FILENAME
17. $document_root$fastcgi_script_name;
18. include fastcgi_params;
19. }
20.}
server {
listen 80;
server_name nginx.org www.nginx.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在匹配location的時候,不是按照配置代碼給出的順序進行匹配的,而是先按照匹配表達式中的文字字元串(literal string)的明確程度,從最明確的開始匹配。這麼說可能有點含混不清,簡單說,沒有正則規則的匹配表達式,是最明確的。比如如果這個匹配表達式就是一個「/」或者「/abc」,那麼這就是最明確的。上例中的"/"就是這個最明確的蚊子字元串(the most specific literal string),其實也是該例中唯一的。所以先從這個location開始,然後再按照location的列出順序,依次匹配,直到出現第一個匹配的location后停止。如果所有的location都不匹配,就用第一個找到的最明確的文字字元串來匹配(the most specific literal string)。
6.待查詢的HTTP請求
Nginx只處理無查詢的HTTP請求,因為查詢請求的查詢欄位的順序不確定,比如:view plaincopy to clipboardprint?
01./index.php?user=john&page=1
02./index.php?page=1&user=john
/index.php?user=john&page=1
/index.php?page=1&user=john再比如:view plaincopy to clipboardprint?
01./index.php?page=1&something+else&user=john
/index.php?page=1&something+else&user=john7.幾個location的例子
例1:view plaincopy to clipboardprint?
01./logo.gif
/logo.gif「/」先被找到,然後匹配"\.(gif|jpg|png)$",再根據redirective找到root是/data/www,然後這個請求就被映射到"/data/www/logo.gif"了,最後文件就被發送給到了客戶端。
例2:view plaincopy to clipboardprint?
01./index.php
/index.php"/"先被找到,然後匹配"\.(php)$",然後request就被傳遞給在9000埠上監聽的FastCGI伺服器,"fastcgi_param" directive設置FastCGI的參數SCRIPT_FILENAME為"/data/www/index.php",然後FastCGI伺服器就執行這個文件。(注意其中document_root是/data/www,fastcgi_script_name是/index.php。)
例3:view plaincopy to clipboardprint?
01./about.html
/about.html"/"先被找到,且只有這一個匹配的。然後根據root值/data/www,就找到了文件/data/www/about.html,然後發送給客戶端。
例4:
view plaincopy to clipboardprint?
01./
/"/"是很複雜的,先找到"/"這個location,然後根據root值/data/www,看/data/www/index.php是否存在,如果存在directive就在內部重定向到/index.php,然後Nginx根據這個再次搜索location,重複上面第二個例子。
《解決方案》
謝謝分享