Nginx 如何處理請求

基於域名的虛擬主機

Nginx 首先決定該請求由哪一個server來處理請求。讓我們以一個簡單的配置文件樣本來說明,這個樣本中的3個虛擬主機都監聽80端口:

  1. server {
  2.     listen       80;
  3.     server_name  nginx.org  www.nginx.org;
  4.     …
  5. }
  6. server {
  7.     listen       80;
  8.     server_name  nginx.net  www.nginx.net;
  9.     …
  10. }
  11. server {
  12.     listen       80;
  13.     server_name  nginx.com  www.nginx.com;
  14.     …
  15. }

在這個配置文件中,Nginx只檢驗其請求的頭部中的“Host”部分,以決定應該選擇用哪一個server去響應。如果“Host”不匹配任何 server,或者請求中不包含“Host”部分,那麼Nginx會用默認的server來響應請求。在上面這個配置文件中,默認的server是第一個 — 這是Nginx默認的標準行爲方式。如果你不希望第一個server作爲默認server,你可以明確地設置一個“default_server”參數在 你所希望的那個server上:

  1. server {
  2.     listen       80  default_server;
  3.     server_name  nginx.net  www.nginx.net;
  4.     …
  5. }

“default_server” 從0.8.21版開始可用。在早期的版本中,應該使用“default”。
注意,默認server匹配端口,不匹配域名。 以後會有更多的擴展。

如何避免處理未被匹配的域名

如果你不想處理那些未被匹配的“Host”行,你可以定義一個默認 server 用來丟棄那些請求:

  1. server {
  2.     listen       80  default_server;
  3.     server_name  _;
  4.     return       444;
  5. }

我們選擇了一個不存在的域名 “_” 作爲 server 名稱並且返回Nginx的特殊代碼‘444’用來關閉連接。注意你應該給這個server設置一個名稱,否則Nginx會使用主機名稱。

基於域名和基於IP的虛擬主機的混用

讓我們看一個更加複雜的配置文件樣本,這個樣本中,那些虛擬 server 監聽着不同的地址:

  1. server {
  2.     listen       192.168.1.1:80;
  3.     server_name  nginx.org  www.nginx.org;
  4.     …
  5. }
  6. server {
  7.     listen       192.168.1.1:80;
  8.     server_name  nginx.net  www.nginx.net;
  9.     …
  10. }
  11. server {
  12.     listen       192.168.1.2:80;
  13.     server_name  nginx.com  www.nginx.com;
  14.     …
  15. }

在這個配置文件中,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對應不同的端口:

  1. server {
  2.     listen        192.168.1.1:80;
  3.     server_name   nginx.org  www.nginx.org;
  4.     …
  5. }
  6. server {
  7.     listen        192.168.1.1:80  default_server;
  8.     server_name   nginx.net  www.nginx.net;
  9.     …
  10. }
  11. server {
  12.     listen        192.168.1.2:80  default_server;
  13.     server_name   nginx.com  www.nginx.com;
  14.     …
  15. }

一個簡單的PHP網站的配置

現在,讓我們用一個典型的、簡單的PHP樣本來看看Ningx如何選擇處理請求時使用的location(位置):

  1. server {
  2.     listen        80;
  3.     server_name   nginx.org  www.nginx.org;
  4.     root          /data/www;
  5.     location / {
  6.         index     index.html  index.php;
  7.     }
  8.     location ~* /.(gif|jpg|png)$ {
  9.         expires   30d;
  10.     }
  11.     location ~ /.php$ {
  12.         fastcgi_pass   localhost:9000;
  13.         fastcgi_param  SCRIPT_FILENAME
  14.                        $document_root$fastcgi_script_name;
  15.         include        fastcgi_params;
  16.     }
  17. }

首先,Nginx 搜索字符location(對應正則表達式location來解釋)所給出的最有效的location(作爲保留位置)。 在上面的配置文件中,唯一的字符location是“/”。因爲它匹配任何請求,所以他會被作爲保留選項。 Nginx檢查配置文件中列出的命令中的正則表達式用以匹配location。第一個匹配的表達式會使搜索停止,然後Nginx會使用這個 location。如果沒有匹配的正則表達式,那麼Nginx會把前面找到的location作爲最後有效的location(保留位置)。

注意所有類型的location只檢驗一個請求中的URI部分,而不包括查詢字符串(?user=…). 這麼做是因爲查詢字符串的參數可以以多種方式出現,比如:

  1. /index.php?user=johnpage=1
  2. /index.php?page=1user=john

除此之外,請求方式不限:

  1. /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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章