基於域名的虛擬主機
Nginx 首先決定該請求由哪一個server來處理請求。讓我們以一個簡單的配置文件樣本來說明,這個樣本中的3個虛擬主機都監聽80端口:
- 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;
- …
- }
在這個配置文件中,Nginx只檢驗其請求的頭部中的“Host”部分,以決定應該選擇用哪一個server去響應。如果“Host”不匹配任何 server,或者請求中不包含“Host”部分,那麼Nginx會用默認的server來響應請求。在上面這個配置文件中,默認的server是第一個 — 這是Nginx默認的標準行爲方式。如果你不希望第一個server作爲默認server,你可以明確地設置一個“default_server”參數在 你所希望的那個server上:
- server {
- listen 80 default_server;
- server_name nginx.net www.nginx.net;
- …
- }
“default_server” 從0.8.21版開始可用。在早期的版本中,應該使用“default”。
注意,默認server匹配端口,不匹配域名。 以後會有更多的擴展。
如何避免處理未被匹配的域名
如果你不想處理那些未被匹配的“Host”行,你可以定義一個默認 server 用來丟棄那些請求:
- server {
- listen 80 default_server;
- server_name _;
- return 444;
- }
我們選擇了一個不存在的域名 “_” 作爲 server 名稱並且返回Nginx的特殊代碼‘444’用來關閉連接。注意你應該給這個server設置一個名稱,否則Nginx會使用主機名稱。
基於域名和基於IP的虛擬主機的混用
讓我們看一個更加複雜的配置文件樣本,這個樣本中,那些虛擬 server 監聽着不同的地址:
- 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;
- …
- }
在這個配置文件中,Nginx首先根據“server” 區塊的“listen”指令檢驗請求中的 IP 地址和端口。 然後根據 “server” 區塊的“server_name”條目檢驗“Host”行所匹配的IP和端口。 如果server名稱沒有找到,那麼該請求會由默認server 處理。 例如, 在192.168.1.1:80上收到的一個對 www.nginx.com 的請求會由192.168.1.1:80 端口的默認 server 來處理, 也就是第一個 server —既然這個端口上不存在www.nginx.com 的定義。
如前所述, 一個默認 server 對應一個端口,不同的默認server對應不同的端口:
- 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;
- …
- }
一個簡單的PHP網站的配置
現在,讓我們用一個典型的、簡單的PHP樣本來看看Ningx如何選擇處理請求時使用的location(位置):
- 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(對應正則表達式location來解釋)所給出的最有效的location(作爲保留位置)。 在上面的配置文件中,唯一的字符location是“/”。因爲它匹配任何請求,所以他會被作爲保留選項。 Nginx檢查配置文件中列出的命令中的正則表達式用以匹配location。第一個匹配的表達式會使搜索停止,然後Nginx會使用這個 location。如果沒有匹配的正則表達式,那麼Nginx會把前面找到的location作爲最後有效的location(保留位置)。
注意所有類型的location只檢驗一個請求中的URI部分,而不包括查詢字符串(?user=…). 這麼做是因爲查詢字符串的參數可以以多種方式出現,比如:
- /index.php?user=johnpage=1
- /index.php?page=1user=john
除此之外,請求方式不限:
- /index.php?page=1something+else&user=john
現在,讓我們看看上面的請求將被如何處理:
一個“/logo.gif”請求會先和字符location“/”匹配,然後再和正則表達式“/.(gif|jpg|png)$”匹配, 因此,它是被字符location處理的。指令“root /data/www”會使該請求指向一個文件 “/data/www/logo.gif”,之後這個文件就會發送到客戶端。
一個 “/index.php”請求同樣先被字符location “/” 匹配,然後才被正則表達式“/.(php)$”匹配。 所以, 它是被字符location所處理的,並且這請求是通過一個監聽在localhost:9000的FastCGI server被處理的. “fastcgi_param” 指令設置FastCGI的參數SCRIPT_FILENAME設置爲“/data/www/index.php”, FastCGI server 執行這個文件. $document_root 變量的值等於 “root” 指令,$fastcgi_script_name 變量等於 URI 請求的值, 也就是 “/index.php”.
一個 “/about.html”請求只被字符location“/”匹配, 所以,它被這個location處理。 使用“root /data/www” 指令的時候,該請求會被轉到 “/data/www/about.html”, 並且文件會被髮送到客戶端。
處理一個 “/”請求更加複雜。 它只被字符location“/”匹配, 因此它被這個location處理。然後 “index” 指令按照它的參數和“root /data/www” 檢驗 index 文件是否存在。如果“/data/www/index.php” 存在, 那麼指令會做內部專向到“/index.php”,然後Nginx 按照客戶端是否發送新請求來再次搜索location。 按照我們前面所看到的,轉向請求最終會被FastCGI server處理。
written by Igor Sysoev
edited by Brian Mercer
Translated by 成歌
轉載地址:http://www.vpsad.com/html/y2010/2840_nginx-how-to-handle-the-request.html