nginx 是如何處理訪問請求的

編譯自:
request_processing

目錄

  • name-based 虛擬主機
  • 對于未定義 server name 的訪問請求趣倾,如何防止其被處理
  • 混合使用 name-based 虛擬主機和 IP-based 虛擬主機
  • 一個簡單的 PHP 站點配置示例

name-based 虛擬主機


當一個訪問請求到達 nginx乒躺,nginx 會考慮選擇某一個 server 處理訪問請求。
我們以一個包含三個 server 區(qū)塊的配置來講解:

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;
    ...
}

這三個虛擬主機均監(jiān)聽于 *:80 端口所宰。根據(jù)上面的配置悲没,nginx 僅通過檢查請求首部中的 “HOST” 字段來決定讓哪個虛擬主機處理訪問請求。如果該字段的值沒有匹配任何虛擬主機形娇,或者請求首部中沒有 “HOST” 字段锰霜,nginx 會將該請求路由到 *:80 端口的默認 server。

在上面的配置中桐早,默認 server 是第一個 server —— 這是 nginx 的標準默認行為癣缅。我們也可以顯式指定一個默認 server,使用 listen 指令的 default_server 參數(shù)來指定哄酝,

例如:

server {
    listen      80 default_server;
    server_name example.net www.example.net;
    ...
}

*Note*:
default_server 參數(shù)從 0.8.21 之后開始使用友存,之前是 default 參數(shù)。

要注意陶衅,默認 server 是監(jiān)聽端口的一個屬性屡立,不是 server name 的屬性。稍后將進一步描述這個問題搀军。

對于未定義 server name 的訪問請求膨俐,如何防止其被處理


如果希望禁止未定義 “Host” 請求首部字段的訪問請求,可設置一個 server 用于丟棄這樣的請求:

 server {
     listen      80;
     server_name "";
     return      444;
 }

我們在這里將 server name 設置為一個空字符串奕巍,它能匹配未攜帶 “Host” 請求首部字段的訪問請求吟策,并且返回一個特殊的狀態(tài)碼 444 以關閉連接,444 不是標準的 nginx 狀態(tài)碼的止。

Note:
從 0.8.48 版開始檩坚,這個設置變成了 nginx 的默認設置,所以 server_name "" 可被刪去诅福。
在更早的版本中匾委,物理主機的主機名被設置為 default server name。

混合使用 name-based 虛擬主機和 IP-based 虛擬主機


現(xiàn)在我們看一個更復雜的配置案例氓润,這里有多個虛擬主機監(jiān)聽于不同的地址:

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;
    ...
}

根據(jù)這份配置赂乐,nginx 首先檢查訪問請求的 IP 地址和端口號,將它與 server 區(qū)塊的 listen 指令的參數(shù)進行對比咖气,過濾掉不匹配的 server挨措。然后 nginx 檢查訪問請求的 “Host” 請求首部字段,將它與剩下的 server 區(qū)塊中的 server_name 進行對比崩溪,看能否匹配浅役。如果沒有匹配的 server,該請求將交給 default server 處理伶唯。

例如觉既,nginx 在 192.168.1.1:80 端口接收到對于 www.example.com 的訪問請求,因為在 192.168.1.1:80 端口沒有匹配的 server name,這個請求最后將被交給 192.168.1.1:80 端口的 default server 處理瞪讼,也就是第一個server钧椰。

正如前面提到過,default server 是監(jiān)聽端口的屬性符欠,所以對于不同的監(jiān)聽端口嫡霞,可以分別為其定義不同的 default server。

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;
    ...
}

192.168.1.1:80 端口的默認 server 是第二個 server背亥;
192.168.1.2:80 端口的默認 server 是第三個 server秒际。

一個簡單的 PHP 站點配置示例


最后我們來看一個 PHP 站點的例子悬赏,看看 nginx 是如何選擇 location 處理請求的:

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 首先根據(jù)訪問請求的 URI 查找匹配的定義了 prefix 前綴的 location狡汉,并記住其中匹配的最長的前綴。在上面的例子中闽颇,定義了前綴的 location 只有一個盾戴,而且前綴為 “/”,它是最短的前綴兵多,能匹配所有請求尖啡。因為 “/” 前綴最短,所以這個 location 總是被作為最后的備選剩膘。

然后 nginx 開始檢查指定了正則表達式的 location衅斩,依照配置文件中的順序依次檢查是否與訪問請求的 URI 匹配,當找到第一個匹配的正則表達式怠褐,nginx 不再繼續(xù)檢查后面的 location畏梆,nginx 將使用找到的第一個匹配正則表達式所對應的 location。如果沒有匹配的 正則表達式奈懒,nginx 將使用之前記住的擁有最長匹配前綴的 location奠涌。

要注意的是,所有類型的 location 僅測試請求的 URI 部分磷杏,不帶參數(shù)溜畅。因為在查詢字符串中的參數(shù),可能以
幾種方式提供:

/index.php?user=john&page=1
/index.php?page=1&user=john

除此之外极祸,在查詢字符串中慈格,任何人可以請求任何事情:

/index.php?page=1&something+else&user=john

現(xiàn)在我們仔細研究一下根據(jù)上面的配置,nginx 將會如何處理訪問請求:

  1. 訪問請求為 “/logo.gif”
    對于 “/logo.gif” 的請求首先被 prefix location “/” 所匹配遥金,然后被正則表達式 “.(gif|jpg|png)$” 所匹配浴捆,因此,這個請求將被交給后者處理汰规。使用 “root /data/www” 指令汤功,該請求被映射為 /data/www/logo.gif,這個文件被發(fā)送給客戶端溜哮。

  2. 訪問請求為 “/index.php”
    對于 “/index.php” 的請求同樣首先被 prefix location “/” 所匹配滔金,然后被正則表達式 “.(php)$” 所匹配色解。因此這個請求將被交給后者處理。該請求被轉發(fā)給一個 FastCGI 服務器餐茵,該服務器監(jiān)聽于: localhost:9000科阎。fastcgi_param 指令用于設置 FastCGI 參數(shù) SCRIPT_FILENAME,這里設置為:“/data/www/index.php”忿族,之后 FastCGI 服務器會執(zhí)行該文件锣笨。$document_root 變量的值等同于 root 指令的參數(shù)值,$fastcgi_script_name 變量的值等于請求 URI道批,即 “/index.php”错英。

  3. 訪問請求為 “/about.html”
    對于 “/about.html” 的請求只能被 prefix location “/” 所匹配。因此該 location 會處理這個 請求隆豹。使用 “root /data/www” 指令椭岩,這個請求被映射到 /data/www/about.html 文件,該文件將被發(fā)送給客戶端璃赡。

  4. 訪問請求為 “/”
    對于 “/” 的訪問請求的處理更為復雜判哥。它只能被 prefix location “/” 所匹配,因此該 location 會處理這個請求碉考。然后 index 指令根據(jù)自己的參數(shù)以及 “root /data/www” 指令塌计,開始測試是否存在 index 文件。如果 /data/www/index.html 文件不存在侯谁,而 /data/www/index.php 文件存在锌仅,index 指令會將請求通過內部重定向,重定向至 “/index.php”良蒸,然后 nginx 如同接收到客戶端發(fā)來對 “/index.php” 的請求開始進行處理技扼。這個處理過程剛才已經講解過,被重定向的請求最后會被轉發(fā)給 FastCGI 服務器進行處理嫩痰。


版權信息
本文編譯自 nginx.org 的部分剿吻,遵循其原來的 licence 聲明: 2-clause BSD-like license

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市串纺,隨后出現(xiàn)的幾起案子丽旅,更是在濱河造成了極大的恐慌,老刑警劉巖纺棺,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件榄笙,死亡現(xiàn)場離奇詭異,居然都是意外死亡祷蝌,警方通過查閱死者的電腦和手機茅撞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人米丘,你說我怎么就攤上這事剑令。” “怎么了拄查?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵吁津,是天一觀的道長。 經常有香客問我堕扶,道長碍脏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上睹耐,老公的妹妹穿的比我還像新娘。我一直安慰自己急黎,他們只是感情好,可當我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布侧到。 她就那樣靜靜地躺著,像睡著了一般淤击。 火紅的嫁衣襯著肌膚如雪匠抗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天污抬,我揣著相機與錄音汞贸,去河邊找鬼。 笑死印机,一個胖子當著我的面吹牛矢腻,可吹牛的內容都是我干的。 我是一名探鬼主播射赛,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼多柑,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了楣责?” 一聲冷哼從身側響起竣灌,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎秆麸,沒想到半個月后初嘹,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡沮趣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年屯烦,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡驻龟,死狀恐怖甸箱,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情迅脐,我是刑警寧澤芍殖,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站谴蔑,受9級特大地震影響豌骏,放射性物質發(fā)生泄漏。R本人自食惡果不足惜隐锭,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一窃躲、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧钦睡,春花似錦蒂窒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至褐桌,卻和暖如春衰抑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背荧嵌。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工呛踊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人啦撮。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓谭网,卻偏偏與公主長得像,于是被迫代替她去往敵國和親赃春。 傳聞我的和親對象是個殘疾皇子愉择,可洞房花燭夜當晚...
    茶點故事閱讀 43,697評論 2 351

推薦閱讀更多精彩內容

  • 上一篇《WEB請求處理一:瀏覽器請求發(fā)起處理》,我們講述了瀏覽器端請求發(fā)起過程聘鳞,通過DNS域名解析服務器IP薄辅,并建...
    七寸知架構閱讀 80,951評論 21 356
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)抠璃,斷路器站楚,智...
    卡卡羅2017閱讀 134,638評論 18 139
  • Nginx簡介 解決基于進程模型產生的C10K問題,請求時即使無狀態(tài)連接如web服務都無法達到并發(fā)響應量級一萬的現(xiàn)...
    魏鎮(zhèn)坪閱讀 1,994評論 0 9
  • 1.ngnix介紹 ngnix www服務軟件 俄羅斯人開發(fā) 開源 性能很高 本身是一款靜態(tài)WWW軟件 靜態(tài)小文件...
    逗比punk閱讀 2,086評論 1 6
  • 配置運行Nginx服務器用戶(組) 用于配置運行Nginx服務器用戶(組)的指令是user,其語法格式為: use...
    吃瓜的東閱讀 4,489評論 0 41