[后端]nginx配置文件詳解

1、nginx配置概覽

概覽

一個(gè)典型的nginx配置文件是由一系列的server塊組成。而每個(gè)server塊是有一系列的location塊組成。server塊是nginx從邏輯上劃分出來的一個(gè)個(gè)的虛擬服務(wù)器,可以從邏輯上認(rèn)為你的服務(wù)器變成多個(gè)了。block塊定義了一個(gè)url路徑該如何定位到正式的文件??傮w來說,nginx處理一個(gè)請(qǐng)求的時(shí)候,先根據(jù)(ip地址,port端口,domain域名)來確定下由哪一個(gè)server塊來進(jìn)行處理,然后server塊再根據(jù)請(qǐng)求的地址來進(jìn)行l(wèi)ocation塊的挑選,location塊內(nèi)部的規(guī)則最終確定下這個(gè)請(qǐng)求怎么返回(直接返回文件內(nèi)容,還是映射成其他請(qǐng)求,還是傳給其他服務(wù)執(zhí)行)。

例子

server {
        listen 123.123.123.123:80;

        server_name lab.example.com;

        root /var/www/html;
        index index.html;

        location /eg {
                 try_files $uri $uri/ =404;
        }

        location /cs {
                 try_files $uri $uri/ =404;
        }
}

server {
        listen 123.123.123.123:80;

        server_name visit.example.com;

        root /var/www/visit;
        index index.html;

        location = /test {
                 try_files $uri $uri/ =404;
        }

        location ^~ /lalal {
                 try_files $uri $uri/ =404;
        }
}

如果我們?cè)L問鏈接http://lab.example.com:80/cs/image.jpg那么就會(huì)由第一個(gè)server的第二個(gè)location來處理。流程是什么樣的呢:

  • step 1 挑選server
  • 檢查ip和port
    nginx發(fā)現(xiàn)請(qǐng)求的ip:port為123.123.123.123:80,對(duì)了一下自己的server列表,發(fā)現(xiàn)兩個(gè)server都滿足。于是要進(jìn)行下一步的檢查
  • 檢查domain域名
    nginx發(fā)現(xiàn)請(qǐng)求的域名為lab.example.com,這下只有第一個(gè)server滿足了,就指派了第一個(gè)server進(jìn)行處理。
  • step 2 挑選location
    請(qǐng)求的location為/cs/image.jpg,第一個(gè)location是匹配以/eg開頭的地址不滿足匹配,第二個(gè)location是匹配以/cs開頭的地址,成功匹配。所以就選了第二個(gè)block進(jìn)行處理。
  • step3 具體處理
    具體處理中是try_files $uri $uri/=404,這里$uri=cs/image.jpg,也就是查看cs/image.jpg這個(gè)文件在/var/www/html目錄下是否存在(全路徑為/var/www/html/cs/image.jpg),如果存在就當(dāng)做文件返回內(nèi)容,如果不存在那么就返回404.

這樣就完成了一個(gè)完整的鏈接請(qǐng)求。

2、server塊詳解

server塊最重要的兩個(gè)屬性是listen和server_name。當(dāng)請(qǐng)求來臨時(shí),listen屬性先用來匹配,如果匹配到唯一server塊那么就是這個(gè)server塊進(jìn)行服務(wù)(就不用考慮server_name是否匹配上了);如果匹配不是唯一的,那么就繼續(xù)使用server_name進(jìn)行匹配。

屬性 含義
listen 定義了該虛擬服務(wù)器監(jiān)聽的ip和port對(duì),只有當(dāng)ip和port同時(shí)匹配的時(shí)候才進(jìn)行下一步匹配
server_name 定義了該虛擬服務(wù)器監(jiān)聽的主機(jī)名,用于當(dāng)ip和port無法確定唯一server塊時(shí)啟用,進(jìn)行進(jìn)一步區(qū)分

listen屬性詳解

  • 屬性格式
形式 描述 例子 默認(rèn)補(bǔ)全
ip地址+port端口 完整形式 listen 123.123.123.123:23 listen 123.123.123.123:23
只有ip 會(huì)自動(dòng)加上80的web監(jiān)聽端口 listen 2.2.2.2 listen 2.2.2.2:80
只有ip 會(huì)自動(dòng)加上0.0.0.0的全監(jiān)聽地址 listen 45 listen 0.0.0.0:45
  • 匹配規(guī)則
    第一步 當(dāng)nginx匹配的時(shí)候,會(huì)將縮寫的格式補(bǔ)全
    第二步 匹配描述的最精確的(縮寫的沒有完整的格式準(zhǔn)確)
    第三步 如果第二步的情況下還有多個(gè),那么listen就判斷不出來了,交給server_name判斷

server_name屬性詳解

  • 屬性格式
形式 例子
不帶有通配符* www.example.com
帶有前綴通配符* *.example.com
帶有后綴通配符* www.example.*
  • 匹配規(guī)則
    優(yōu)先匹配不帶通配符的完整表達(dá)
    接著匹配帶有前綴通配符的表達(dá)
    最后匹配帶有后綴通配符的表達(dá)

當(dāng)兩個(gè)表達(dá)帶通配符的形式相同的時(shí)候,匹配最長的那個(gè)。

3、location塊詳解

  • 語法
location optional_modifier location_match { 
   ...
}  

語法中的optional_modifier是描述符,location_match是具體匹配的串形式,如果描述符是正則的一種,那么就會(huì)以正則的方式來對(duì)待location_match,否則以普通方式用location_match來當(dāng)前綴匹配。

  • optional_modifier

|類型|含義|匹配方式|優(yōu)先級(jí)|例子|
|:--|:--|:--|:--|
|(none)|最普通的前綴匹配|前綴方式匹配|4|location / {}|
|=|要求絕對(duì)相等|前綴方式匹配|1|location = /image {}|
|~|區(qū)分大小寫的正則匹配|正則方式匹配|3|location ~ .(jpe?g)$ {}|
|~|不區(qū)分大小寫的正則匹配|正則方式匹配|3|location ~ .(jpe?g)$ {}|
|^~|高優(yōu)先級(jí)的前綴匹配|前綴方式匹配|2|location ^~ /page {}|

  • 匹配規(guī)則

  • 最高優(yōu)先級(jí)的是=,這個(gè)只能完全相等才能匹配上,如果找到符合條件的那么完成匹配。

  • 接著在~和(none)中找到一個(gè)能夠匹配出最長串的<sup>1</sup>規(guī)則,如果這個(gè)規(guī)則是屬于~的,那么完成匹配。

  • 否則如果上一步中規(guī)則是屬于(none)的,則還需要給正則表達(dá)式驗(yàn)證一下。這時(shí)候按照location定義的順序一個(gè)一個(gè)地檢測*和規(guī)則,如果發(fā)現(xiàn)一個(gè)滿足的,那么就用這條正則規(guī)則。

  • 最后如果正則規(guī)則中沒有符合條件的,那么就用剛才屬于(none)的規(guī)則,如果剛才連各最長串都沒有,那就跳到默認(rèn)location去了。

  • 注釋1例子

server {
  location = /abc {...}
  location / {...}
  location ^~ /big/middle {...}
  location /big/middle/small {...}
  location ~ 123+\.jpg {...}
  location ~* a+\.jpg {...}
}

如果我們要匹配\big\middle\small的話,是不會(huì)匹配到location ^~ \big\middle {...}這條規(guī)則的,因?yàn)楫?dāng)=規(guī)則匹配結(jié)束沒找到之后,就回去找(none)和^~中匹配最長的一條,這時(shí)候最長的是(none)的location \big\middle\small {...},然后在進(jìn)行正則匹配,發(fā)現(xiàn)沒有滿足的,于是就取(none)的這一條了。這一點(diǎn)要注意。

4、目錄配置

在上述步驟后,我們知道一個(gè)請(qǐng)求具體定位到location的過程,現(xiàn)在來繼續(xù)探究location之后的相應(yīng)處理。首先是location中的資源應(yīng)該對(duì)應(yīng)在哪一個(gè)服務(wù)器目錄中呢?這就需要root屬性來指定了。
root屬性可以定義在server塊中,也可以定義在location塊中。如果聲明在server塊中那么所有的location都會(huì)繼承這個(gè)定義。同時(shí)若location中也定義了root屬性,那么以location中的定義為主。
舉個(gè)例子

server {
  ...
  root /var/www/html

  location /cs {
     root /share/usr
     try_files $uri $uri/ =404;
  }

  location /eg {
     try_files $uri $uri/ =404;
  }
}

如果訪問/cs/vr/audio.mp3,那么就會(huì)對(duì)應(yīng)到服務(wù)器上的/share/usr/cs/vr/audio.mp3的資源
如果訪問/eg/file/new.pdf,那么就會(huì)對(duì)應(yīng)到服務(wù)器上的/var/www/html/eg/file/new.pdf的資源

再比如用nginx上架設(shè)codeigniter框架,我們需要重寫url那么我們這樣

server {
        listen       80 ;
        listen       [::]:80;
        server_name  ci.example.com;
        root /var/www/example;

        location / {
                rewrite ^(.*)$ /index.php?$1 last;
        }

        location ~ \.php$ {
                fastcgi_pass   127.0.0.1:9000;
                fastcgi_index  index.php;
                fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
                include        fastcgi_params;
        }

        error_page 404 /404.html;
        location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
}

那么這樣,對(duì)于一個(gè)非.php的文件,都為在第一個(gè)location中重寫成/index.php?$uri的形式重寫進(jìn)行一次搜索。這時(shí)候必然被第二個(gè)location接收(前綴匹配的更長嘛),這樣就完成了codeigniter的定位。
比如我們?cè)L問ci.example.com/hello就會(huì)被重定向到訪問var/www/example/index.php?hello同時(shí)被pass給php的cgi進(jìn)行處理。

參考材料

Understanding Nginx Server and Location Block Selection Algorithms
how-to-configure-nginx

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,569評(píng)論 19 139
  • 1.ngnix介紹 ngnix www服務(wù)軟件 俄羅斯人開發(fā) 開源 性能很高 本身是一款靜態(tài)WWW軟件 靜態(tài)小文件...
    逗比punk閱讀 2,237評(píng)論 1 6
  • Nginx簡介 解決基于進(jìn)程模型產(chǎn)生的C10K問題,請(qǐng)求時(shí)即使無狀態(tài)連接如web服務(wù)都無法達(dá)到并發(fā)響應(yīng)量級(jí)一萬的現(xiàn)...
    魏鎮(zhèn)坪閱讀 2,214評(píng)論 0 9
  • location正則寫法 location使用語法: location [ = | ~ | ~* | ^~ ] u...
    Zhang21閱讀 14,890評(píng)論 0 5
  • 配置運(yùn)行Nginx服務(wù)器用戶(組) 用于配置運(yùn)行Nginx服務(wù)器用戶(組)的指令是user,其語法格式為: use...
    吃瓜的東閱讀 4,687評(píng)論 0 41

友情鏈接更多精彩內(nèi)容