久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長(zhǎng)資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      Nginx執(zhí)行階段詳細(xì)解析

      Nginx 介紹
      Nginx (engine x) 是一個(gè)高性能的HTTP和反向代理服務(wù)器,也是一個(gè)IMAP/POP3/SMTP服務(wù)器。
      Nginx是一款輕量級(jí)的Web 服務(wù)器/反向代理服務(wù)器及電子郵件(IMAP/POP3)代理服務(wù)器,并在一個(gè)BSD-like 協(xié)議下發(fā)行。其特點(diǎn)是占有內(nèi)存少,并發(fā)能力強(qiáng)
      OpenResty介紹
      OpenResty 是一個(gè)基于 Nginx 與 Lua 的高性能 Web 平臺(tái),其內(nèi)部集成了大量精良的 Lua 庫(kù)、第三方模塊以及大多數(shù)的依賴(lài)項(xiàng)。用于方便地搭建能夠處理超高并發(fā)、擴(kuò)展性極高的動(dòng)態(tài) Web 應(yīng)用、Web 服務(wù)和動(dòng)態(tài)網(wǎng)關(guān)

      執(zhí)行階段前言

      location /test {  set $a 32;  echo $a;    set $a 56;  echo $a;  }

      兩次都會(huì)輸出56,因?yàn)閟et階段始終在content階段之前執(zhí)行,跟代碼的先后順序無(wú)關(guān)。

      Nginx執(zhí)行階段

      Nginx 處理請(qǐng)求的過(guò)程一共劃分為 11 個(gè)階段,按照?qǐng)?zhí)行順序依次是 post-read、server-rewrite、find-config、rewrite、post-rewrite、preaccess、access、post-access、try-files、content 以及 log

      post-read 階段

      該階段Nginx標(biāo)準(zhǔn)函數(shù) set_real_ip_from、real_ip_header
      最先執(zhí)行的 post-read 階段在 Nginx 讀取并解析完請(qǐng)求頭(request headers)之后就立即開(kāi)始運(yùn)行。標(biāo)準(zhǔn)模塊 ngx_realip 就在 post-read 階段注冊(cè)了處理程序,它的功能是迫使 Nginx 認(rèn)為當(dāng)前請(qǐng)求的來(lái)源地址是指定的某一個(gè)請(qǐng)求頭的值。下面這個(gè)例子就使用了 ngx_realip 模塊提供的 set_real_ip_from 和 real_ip_header

      server {      listen 8080;      set_real_ip_from 127.0.0.1;      real_ip_header   X-My-IP;        location /test {          set $addr $remote_addr;          echo "from: $addr";      }  }

      這里的配置是讓 Nginx 把那些來(lái)自 127.0.0.1 的所有請(qǐng)求的來(lái)源地址,都改寫(xiě)為請(qǐng)求頭 X-My-IP 所指定的值。同時(shí)該例使用了標(biāo)準(zhǔn)內(nèi)建變量 $remote_addr 來(lái)輸出當(dāng)前請(qǐng)求的來(lái)源地址,以確認(rèn)是否被成功改寫(xiě)。

      $ curl -H 'X-My-IP: 1.2.3.4' localhost:8080/test      from: 1.2.3.4

      server-rewrite階段

      該階段包含標(biāo)準(zhǔn)函數(shù)ngx_rewrite、set 以及openresty函數(shù)set_by_lua、rewrite_by_lua
      post-read 階段之后便是 server-rewrite 階段。當(dāng) ngx_rewrite 模塊的配置指令直接書(shū)寫(xiě)在 server 配置塊中時(shí),基本上都是運(yùn)行在 server-rewrite 階段。

      server {      listen 8080;        location /test {          set $b "$a, world";          echo $b;      }        set $a hello;  }

      這里,配置語(yǔ)句 set $a hello 直接寫(xiě)在了 server 配置塊中,因此它就運(yùn)行在 server-rewrite 階段。而 server-rewrite 階段要早于 rewrite 階段運(yùn)行,因此寫(xiě)在 location 配置塊中的語(yǔ)句 set $b “$a, world” 便晚于外面的 set $a hello 語(yǔ)句運(yùn)行。該例的測(cè)試結(jié)果證明了這一點(diǎn):

      $ curl localhost:8080/test  hello, world

      find-config 階段

      這個(gè)階段并不支持 Nginx 模塊注冊(cè)處理程序,而是由 Nginx 核心來(lái)完成當(dāng)前請(qǐng)求與 location 配置塊之間的配對(duì)工作。

      location /hello {      echo "hello world";  }

      rewrite 階段

      該階段包含標(biāo)準(zhǔn)函數(shù)set_unescape_uri、rewrite以及openresty函數(shù)set_by_lua、 rewrite_by_lua

      post-rewrite 階段

      post-rewrite 階段,不接受 Nginx 模塊注冊(cè)處理程序,而是由 Nginx 核心完成 rewrite 階段所要求的“內(nèi)部跳轉(zhuǎn)”操作
      “內(nèi)部跳轉(zhuǎn)”的工作原理:本質(zhì)上其實(shí)就是把當(dāng)前的請(qǐng)求處理階段強(qiáng)行倒退到 find-config 階段,以便重新進(jìn)行請(qǐng)求 URI 與 location 配置塊的配對(duì)。比如例中,運(yùn)行在 rewrite 階段的 rewrite 指令就讓當(dāng)前請(qǐng)求的處理階段倒退回了 find-config 階段。由于此時(shí)當(dāng)前請(qǐng)求的 URI 已經(jīng)被 rewrite 指令修改為了 /bar,所以這一次換成了 location /bar 與當(dāng)前請(qǐng)求相關(guān)聯(lián),然后再接著從 rewrite 階段往下執(zhí)行。
      為什么不直接在 rewrite 指令執(zhí)行時(shí)立即進(jìn)行跳轉(zhuǎn)呢?
      為了在最初匹配的 location 塊中支持多次反復(fù)地改寫(xiě) URI

          server {          listen 8080;            location /foo {              set $a hello;              rewrite ^ /bar;          }            location /bar {              echo "a = [$a]";          }      }
      location /foo {      rewrite ^ /bar;      rewrite ^ /baz;        echo foo;  }    location /bar {      echo bar;  }    location /baz {      echo baz;  }

      注意的:如果在 server 配置塊中直接使用 rewrite 配置指令對(duì)請(qǐng)求 URI 進(jìn)行改寫(xiě),則不會(huì)涉及“內(nèi)部跳轉(zhuǎn)”

      server {  listen 8080;    rewrite ^/foo /bar;    location /foo {      echo foo;  }    location /bar {      echo bar;  }  }

      preaccess 階段

      該階段包含標(biāo)準(zhǔn)函數(shù)ngx_access-allow deny ngx_limit_req 和 ngx_limit_zone ngx_auth_request 以及openresty函數(shù)access_by_lua其中也包含了限頻限流模塊resty.limit.req resty.limit.conn
      注意的是:標(biāo)準(zhǔn)模塊 ngx_realip 其實(shí)也在這個(gè)階段注冊(cè)了處理程序

      server {      listen 8080;        location /test {          set_real_ip_from 127.0.0.1;          real_ip_header X-Real-IP;            echo "from: $remote_addr";      }  }

      與先看前到的例子相比,此例最重要的區(qū)別在于把 ngx_realip 的配置指令放在了 location 配置塊中。前面我們介紹過(guò),Nginx 匹配 location 的動(dòng)作發(fā)生在 find-config 階段,而 find-config 階段遠(yuǎn)遠(yuǎn)晚于 post-read 階段執(zhí)行,所以在 post-read 階段,當(dāng)前請(qǐng)求還沒(méi)有和任何 location 相關(guān)聯(lián)。
      建議是:盡量在 server 配置塊中配置 ngx_realip 這樣的模塊

      post-access階段

      該階段不支持 Nginx 模塊注冊(cè)處理程序,而是由 Nginx 核心自己完成一些處理工作

      try-files 階段

      實(shí)現(xiàn)標(biāo)準(zhǔn)配置指令 try_files 的功能,并不支持 Nginx 模塊注冊(cè)處理程序。
      try_files 指令接受兩個(gè)以上任意數(shù)量的參數(shù),每個(gè)參數(shù)都指定了一個(gè) URI. 這里假設(shè)配置了 N 個(gè)參數(shù),則 Nginx 會(huì)在 try-files 階段,依次把前 N-1 個(gè)參數(shù)映射為文件系統(tǒng)上的對(duì)象(文件或者目錄),然后檢查這些對(duì)象是否存在。一旦 Nginx 發(fā)現(xiàn)某個(gè)文件系統(tǒng)對(duì)象存在,就會(huì)在 try-files 階段把當(dāng)前請(qǐng)求的 URI 改寫(xiě)為該對(duì)象所對(duì)應(yīng)的參數(shù) URI(但不會(huì)包含末尾的斜杠字符,也不會(huì)發(fā)生 “內(nèi)部跳轉(zhuǎn)”)。如果前 N-1 個(gè)參數(shù)所對(duì)應(yīng)的文件系統(tǒng)對(duì)象都不存在,try-files 階段就會(huì)立即發(fā)起“內(nèi)部跳轉(zhuǎn)”到最后一個(gè)參數(shù)(即第 N 個(gè)參數(shù))所指定的 URI.

      location /test {      try_files /foo /bar/ /baz;      echo "uri: $uri";  }    location /foo {      echo foo;  }    location /bar/ {      echo bar;  }    location /baz {      echo baz;  }

      我們?cè)?location /test 中使用了 try_files 配置指令,并提供了三個(gè)參數(shù),/foo、/bar/ 和 /baz. 根據(jù)前面對(duì) try_files 指令的介紹,我們可以知道,它會(huì)在 try-files 階段依次檢查前兩個(gè)參數(shù) /foo 和 /bar/ 所對(duì)應(yīng)的文件系統(tǒng)對(duì)象是否存在。
      不妨先來(lái)做一組實(shí)驗(yàn)。假設(shè)現(xiàn)在 /var/www/ 路徑下是空的,則第一個(gè)參數(shù) /foo 映射成的文件 /var/www/foo 是不存在的;同樣,對(duì)于第二個(gè)參數(shù) /bar/ 所映射成的目錄 /var/www/bar/ 也是不存在的。于是此時(shí) Nginx 會(huì)在 try-files 階段發(fā)起到最后一個(gè)參數(shù)所指定的 URI(即 /baz)的“內(nèi)部跳轉(zhuǎn)”。實(shí)際的請(qǐng)求結(jié)果證實(shí)了這一點(diǎn):

       $ curl localhost:8080/test     baz

      接下來(lái)再做一組實(shí)驗(yàn):在 /var/www/ 下創(chuàng)建一個(gè)名為 foo 的文件,其內(nèi)容為 hello world(注意你需要有 /var/www/ 目錄下的寫(xiě)權(quán)限):

      $ echo 'hello world' > /var/www/foo

      然后再請(qǐng)求 /test 接口:

       $ curl localhost:8080/test    uri: /foo

      這里發(fā)生了什么?我們來(lái)看, try_files 指令的第一個(gè)參數(shù) /foo 可以映射為文件 /var/www/foo,而 Nginx 在 try-files 階段發(fā)現(xiàn)此文件確實(shí)存在,于是立即把當(dāng)前請(qǐng)求的 URI 改寫(xiě)為這個(gè)參數(shù)的值,即 /foo,并且不再繼續(xù)檢查后面的參數(shù),而直接運(yùn)行后面的請(qǐng)求處理階段。
      通過(guò)前面這幾組實(shí)驗(yàn)不難看到, try_files 指令本質(zhì)上只是有條件地改寫(xiě)當(dāng)前請(qǐng)求的 URI,而這里說(shuō)的“條件”其實(shí)就是文件系統(tǒng)上的對(duì)象是否存在。當(dāng)“條件”都不滿(mǎn)足時(shí),它就會(huì)無(wú)條件地發(fā)起一個(gè)指定的“內(nèi)部跳轉(zhuǎn)”。當(dāng)然,除了無(wú)條件地發(fā)起“內(nèi)部跳轉(zhuǎn)”之外, try_files 指令還支持直接返回指定狀態(tài)碼的 HTTP 錯(cuò)誤頁(yè),例如:

       try_files /foo /bar/ =404;

      這行配置是說(shuō),當(dāng) /foo 和 /bar/ 參數(shù)所對(duì)應(yīng)的文件系統(tǒng)對(duì)象都不存在時(shí),就直接返回 404 Not Found 錯(cuò)誤頁(yè)。注意這里它是如何使用等號(hào)字符前綴來(lái)標(biāo)識(shí) HTTP 狀態(tài)碼的。

      content階段

      該階段包含標(biāo)準(zhǔn)函數(shù)echo proxy_pass 以及openresty 函數(shù)content_by_lua balance_by_lua header_filter_by_lua body_filter_by_lua
      log

      所有請(qǐng)求的標(biāo)準(zhǔn)輸出都在改階段。幾乎所有的邏輯代碼也在改階段執(zhí)行。這個(gè)階段比較常見(jiàn)

      log階段

      改階段包含ngx的acces_log error_log以及openresty函數(shù)log_by_lua
      該階段主要記錄日志

      其它

      satisfy指令

      對(duì)于多個(gè) Nginx 模塊注冊(cè)在 access 階段的處理程序, satisfy 配置指令可以用于控制它們彼此之間的協(xié)作方式。比如模塊 A 和 B 都在 access 階段注冊(cè)了與訪(fǎng)問(wèn)控制相關(guān)的處理程序,那就有兩種協(xié)作方式,一是模塊 A 和模塊 B 都得通過(guò)驗(yàn)證才算通過(guò),二是模塊 A 和模塊 B 只要其中任一個(gè)通過(guò)驗(yàn)證就算通過(guò)。第一種協(xié)作方式稱(chēng)為 all 方式(或者說(shuō)“與關(guān)系”),第二種方式則被稱(chēng)為 any 方式(或者說(shuō)“或關(guān)系”)。默認(rèn)情況下,Nginx 使用的是 all 方式。

      location /test {      satisfy all;        deny all;      access_by_lua 'ngx.exit(ngx.OK)';        echo something important;  }

      如果我們把上例中的 satisfy all 語(yǔ)句更改為 satisfy any,

      location /test {      satisfy any;        deny all;      access_by_lua 'ngx.exit(ngx.OK)';        echo something important;  }

      結(jié)果則會(huì)完全不同:

      $ curl localhost:8080/test  something important

      在 any 方式下,access 階段只要有一個(gè)模塊通過(guò)了驗(yàn)證,就會(huì)認(rèn)為請(qǐng)求整體通過(guò)了驗(yàn)證,而在上例中, ngx_lua 模塊的 access_by_lua 語(yǔ)句總是會(huì)通過(guò)驗(yàn)證的。

      ngx_index 模塊, ngx_autoindex 模塊,以及 ngx_static 模塊

      Nginx 一般會(huì)在 content 階段安排三個(gè)這樣的靜態(tài)資源服務(wù)模塊。按照它們?cè)?content 階段的運(yùn)行順序,依次是 ngx_index 模塊, ngx_autoindex 模塊,以及 ngx_static 模塊。
      ngx_index 和 ngx_autoindex 模塊都只會(huì)作用于那些 URI 以 / 結(jié)尾的請(qǐng)求,例如請(qǐng)求 GET /cats/,而對(duì)于不以 / 結(jié)尾的請(qǐng)求則會(huì)直接忽略,同時(shí)把處理權(quán)移交給 content 階段的下一個(gè)模塊。而 ngx_static 模塊則剛好相反,直接忽略那些 URI 以 / 結(jié)尾的請(qǐng)求。
      ngx_index 模塊主要用于在文件系統(tǒng)目錄中自動(dòng)查找指定的首頁(yè)文件,類(lèi)似 index.html 和 index.htm 這樣的,例如:

      location / {      root /var/www/;      index index.htm index.html;  }

      為了進(jìn)一步確認(rèn) ngx_index 模塊在找到文件時(shí)的“內(nèi)部跳轉(zhuǎn)”行為,我們不妨設(shè)計(jì)下面這個(gè)小例子:

      location / {      root /var/www/;      index index.html;  }    location /index.html {      set $a 32;      echo "a = $a";  }

      此時(shí)我們?cè)诒緳C(jī)的 /var/www/ 目錄下創(chuàng)建一個(gè)空白的 index.html 文件,并確保該文件的權(quán)限設(shè)置對(duì)于運(yùn)行 Nginx worker 進(jìn)程的帳戶(hù)可讀

      $ curl 'http://localhost:8080/'  a = 32

      如果此時(shí)把 /var/www/index.html 文件刪除,再訪(fǎng)問(wèn) / 又會(huì)發(fā)生什么事情呢?答案是返回 403 Forbidden 出錯(cuò)頁(yè)。為什么呢?因?yàn)?ngx_index 模塊找不到 index 指令指定的文件(在這里就是 index.html),接著把處理權(quán)轉(zhuǎn)給 content 階段的后續(xù)模塊,而后續(xù)的模塊也都無(wú)法處理這個(gè)請(qǐng)求,于是 Nginx 只好放棄,輸出了錯(cuò)誤頁(yè)
      運(yùn)行在 ngx_index 模塊之后的 ngx_autoindex 模塊就可以用于自動(dòng)生成這樣的“目錄索引”網(wǎng)頁(yè)。我們來(lái)把上例修改一下:

      location / {      root /var/www/;      index index.html;      autoindex on;  }

      此時(shí)仍然保持文件系統(tǒng)中的 /var/www/index.html 文件不存在。我們?cè)僭L(fǎng)問(wèn) / 位置時(shí),就會(huì)得到一張漂亮的網(wǎng)頁(yè):

      $ curl 'http://localhost:8080/'

      ngx_static 模塊服務(wù)磁盤(pán)文件的例子。我們使用下面這個(gè)配置片段:
      location / {
      root /var/www/;
      }

      現(xiàn)在來(lái)通過(guò) HTTP 協(xié)議請(qǐng)求一下這兩個(gè)文件所對(duì)應(yīng)的 URI:

      $ curl 'http://localhost:8080/index.html'  this is my home    $ curl 'http://localhost:8080/hello.html'  hello world

      location / 中沒(méi)有使用運(yùn)行在 content 階段的模塊指令,于是也就沒(méi)有模塊注冊(cè)這個(gè) location 的“內(nèi)容處理程序”,處理權(quán)便自動(dòng)落到了在 content 階段“墊底”的那 3 個(gè)靜態(tài)資源服務(wù)模塊。首先運(yùn)行的 ngx_index 和 ngx_autoindex 模塊先后看到當(dāng)前請(qǐng)求的 URI,/index.html 和 /hello.html,并不以 / 結(jié)尾,于是直接棄權(quán),將處理權(quán)轉(zhuǎn)給了最后運(yùn)行的 ngx_static 模塊。ngx_static 模塊根據(jù) root 指令指定的“文檔根目錄”(document root),分別將請(qǐng)求 URI /index.html 和 /hello.html 映射為文件系統(tǒng)路徑 /var/www/index.html 和 /var/www/hello.html,在確認(rèn)這兩個(gè)文件存在后,將它們的內(nèi)容分別作為響應(yīng)體輸出,并自動(dòng)設(shè)置 Content-Type、Content-Length 以及 Last-Modified 等響應(yīng)頭。

      很多初學(xué)者會(huì)想當(dāng)然地把 404 錯(cuò)誤理解為某個(gè) location 不存在,其實(shí)上面這個(gè)例子表明,即使 location 存在并成功匹配,也是可能返回 404 錯(cuò)誤頁(yè)的。因?yàn)闆Q定著 404 錯(cuò)誤頁(yè)的是抽象的“資源”是否存在,而非某個(gè)具體的 location 是否存在。
      location /auth {
      access_by_lua ‘
      ‘;
      }
      顯然,這個(gè) /auth 接口只定義了 access 階段的配置指令,即 access_by_lua,并未定義任何 content 階段的配置指令。于是當(dāng)我們請(qǐng)求 /auth 接口時(shí),在 access 階段的 Lua 代碼會(huì)如期執(zhí)行,然后 content 階段的那些靜態(tài)文件服務(wù)會(huì)緊接著自動(dòng)發(fā)生作用,直至 ngx_static 模塊去文件系統(tǒng)上找名為 auth 的文件。而經(jīng)常地,404 錯(cuò)誤頁(yè)會(huì)拋出,除非運(yùn)氣太好,在對(duì)應(yīng)路徑上確實(shí)存在一個(gè)叫做 auth 的文件。所以,一條經(jīng)驗(yàn)是,當(dāng)遇到意外的 404 錯(cuò)誤并且又不涉及靜態(tài)文件服務(wù)時(shí),應(yīng)當(dāng)首先檢查是否在對(duì)應(yīng)的 location 配置塊中恰當(dāng)?shù)嘏渲昧?content 階段的模塊指令,例如 content_by_lua、 echo 以及 proxy_pass 之類(lèi)。

      openresty請(qǐng)求處理順序

      set_by_lua: 流程分支處理判斷變量初始化
      rewrite_by_lua
      : 轉(zhuǎn)發(fā)、重定向、緩存等功能(例如特定請(qǐng)求代理到外網(wǎng))
      access_by_lua: IP 準(zhǔn)入、接口權(quán)限等情況集中處理(例如配合 iptable 完成簡(jiǎn)單防火墻)
      content_by_lua
      : 內(nèi)容生成
      header_filter_by_lua: 響應(yīng)頭部過(guò)濾處理(例如添加頭部信息)
      body_filter_by_lua
      : 響應(yīng)體過(guò)濾處理(例如完成應(yīng)答內(nèi)容統(tǒng)一成大寫(xiě)) log_by_lua*:會(huì)話(huà)完成后本地異步完成日志記錄(日志可以記錄在本地,還可以同步到其他機(jī)器)

      Nginx執(zhí)行階段詳細(xì)解析

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)