NGINX openrestry(指令的執行順序)


Nginx的指令的執行順序:

一、post-read

  ngx_realip模塊的set_real_ip_from和real_ip_header指令(在server里面配置的)

二、server-rewrite

  subrequest子請求從這個階段開始執行。

  ngx_rewrite模塊的set指令和rewrite指令(前提在server里面配置時)

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

 

三、find-config(不接受模塊注冊處理程序)

  進行location的配對

四、rewrite

  ngx_rewrite模塊的set指令和rewrite指令(前提在location里面配置時)

  ngx_set_misc模塊的set_unescape_uri指令

  ngx_lua模塊的set_by_lua指令(set_by_lua 指令確實也可以和 set 這樣的 ngx_rewrite 模塊提供的指令混合在一起工作)

  rewrite tail:

  ngx_headers_more模塊的more_set_input_headers指令

  ngx_lua模塊的rewrite_by_lua指令

五、post-rewrite(不接受模塊注冊處理程序)

  實現在rewrite階段的內部跳轉

  “內部跳轉”本質上其實就是把當前的請求處理階段強行倒退到 find-config 階段,以便重新進行請求URI 與 location 配置塊的配對

  rewrite階段的rewrite指令

location /foo {
  rewrite ^ /bar;
  rewrite ^ /baz;
  echo foo;
}

  兩個rewrite語句都會執行,但只有最后一個才會起作用。因為rewrite指令在rewrite階段執行,但是真正的內部跳轉確是在post-rewrite階段

六、preaccess

  ngx_realip模塊的set_real_ip_from和real_ip_header指令(在location里面配置的)

七、access

  ngx_access模塊的allow指令和deny指令(多個指令會按順序進行執行)

  如果首先匹配的指令是 allow,則會繼續執行后續其他模塊的指令或者跳到后續的處理階段;而如果首先滿足的是 deny 則會立即中止當前整個請求的處理,並立即返回 403 錯誤頁。

  access tail:

  ngx_lua模塊的access_by_lua指令

  tips:指令中return表示該指令就是,繼續執行后續的指令。

  tips:ngx_lua模塊的ngx.exit(403)函數,直接結束整個請求處理過程,返回403頁面。

八、post-access(不接受模塊注冊處理程序)

  ngx_http_core模塊的satisfy指令

  對於多個 Nginx 模塊注冊在 access 階段的處理程序, satisfy 配置指令可以用於控制它們彼此之間的協作方式。比如模塊 A 和 B 都在 access 階段注冊了與訪問控制相關的處理程序,那就有兩種協作方式,一是模塊 A 和模塊 B 都得通過驗證才算通過,二是模塊 A 和模塊 B 只要其中任一個通過驗證就算通過。第一種協作方式稱為 all 方式(或者說“與關系”),第二種方式則被稱為 any 方式(或者說“或關系”)。默認情況下,Nginx 使用的是 all 方式。

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

  比如上面這個就是在access階段的ngx_access模塊的程序和ngx_lua模塊的關系是與的關系,兩個都通過才可以。由於deny all,所以就都返回403了。

  deny all和access_by_lua 'ngx.exit(ngx.HTTP_FORBIDDEN)';效果一樣。

九、try-files(不接受模塊注冊處理程序)

  配置指令try_files

  try_files 指令接受兩個以上任意數量的參數,每個參數都指定了一個 URI. 這里假設配置了 N 個參數,則 Nginx 會在 try-files 階段,依次把前 N-1 個參數映射為文件系統上的對象(文件或者目錄),然后檢查這些對象是否存在。一旦 Nginx 發現某個文件系統對象存在,就會在 try-files 階段把當前請求的 URI 改寫為該對象所對應的參數 URI(但不會包含末尾的斜杠字符,也不會發生 “內部跳轉”),然后執行下一個階段。如果前 N-1 個參數所對應的文件系統對象都不存在,try-files 階段就會立即發起“內部跳轉”到最后一個參數(即第 N 個參數)所指定的 URI.

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

  curl localhost:8000/test

  baz

  假設現在 /var/www/ 路徑下是空的,則第一個參數 /foo 映射成的文件 /var/www/foo 是不存在的;同樣,對於第二個參數/bar/ 所映射成的目錄 /var/www/bar/ 也是不存在的。於是此時 Nginx 會在 try-files 階段發起到最后一個參數所指定的 URI(即 /baz)的“內部

跳轉”。當/bar/目錄存在時,URI會被改寫成/bar,末尾的'/'會被去掉。

  當然,除了無條件地發起“內部跳轉”之外, try_files 指令還支持直接返回指定狀態碼的HTTP 錯誤頁,例如:try_files /foo /bar/ =404;

十、content階段:

  這個階段的這么多的指令只能有一種勝出。每一個location只能有一個內容處理程序。

  執行的順序是:如果1里面有就從里面選擇一個執行,如果1里面沒有就讓2執行,如果2沒有或者處理不了就讓3執行,如果3沒有或者處理不了就讓4執行。

1、ngx_echo模塊的echo指令、echo_exec指令、echo_location指令

  ngx_proxy模塊的proxy_pass指令

  ngx_lua模塊的content_by_lua指令

  用一種指令有的可以寫幾次,比如echo。

location /test {
  echo hello;
  echo world;
}

  ngx_lua模塊的ngx.say函數和ngx_echo模塊的echo函數是一樣的

location /test {
  content_by_lua 'ngx.say("hello") ngx.say("world")';
}

tips:當“文檔根目錄”是 /var/www/ 的時候,請求 URI /foo/bar 會被映射為文件 /var/www/foo/bar,而請求 URI /foo/baz/ 則會被映射為目錄/var/www/foo/baz/. 注意這里是如何通過 URI 末尾的斜杠字符是否存在來區分“目錄”和“文件”的。(這個是對於2、3、4來說的)

2、ngx_index模塊的index指令:(會找root目錄拼接uri目錄下的文件是否存在)

  處理以'/'結尾的請求

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

  當用戶請求'/'地址時,Nginx會自動在/var/www/index.htm目錄下尋找這個文件,如果找到,則直接發起內部跳轉到新的'/index.html'這個新的地址,如果不存在,則繼續找/var/www/index.html這個文件,如果找得到,則直接發起內部跳轉到'/index.html'這個地址,如果不存在,就交給后續的模塊進行處理,如果都處理不了,就報403的錯誤。

3、ngx_autoindex模塊的autoindex指令:(會找root目錄拼接uri目錄下的文件是否存在)

  處理以'/'結尾的請求

  自動生成目錄索引頁

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

  當請求到來時,當/var/www/index.html的頁面不存在時,會顯示/var/www/下的文件目錄列表;當index.html的存在時,會優先執行ngx_index模塊的index指令,直接發生內部跳轉。

4、ngx_static模塊的靜態資源指令:(會找root目錄拼接uri目錄下的文件是否存在)

  處理不以'/'結尾的網頁

  專門用來處理和輸出靜態資源內容的

location / {
  root /var/www/ }

  因為沒有配置 root 指令,所以在訪問這個接口時,Nginx 會自動計算出一個缺省的“文檔根目錄”。該缺省值是取所謂的“配置前綴 prefix路徑下的 html/ 子目錄。舉一個例子,假設配置前綴是 /foo/bar/,則缺省的“文檔根目錄”便是 /foo/bar/html/。

  當靜態資源找不到時會出現404錯誤。404是指靜態資源找不到,而並非location找不到。當然如果location找不到也是404。

十一、log

參考知識點:

1、內部跳轉:(瀏覽器地址不發生變化)

  ngx_index模塊的index指令

  echo模塊的echo_exec指令

  ngx_rewrite模塊的rewrite指令

  try_files的最后一跳

2、HTTP的頭部參數的獲取

  $http_XXX 內建變量在讀取時會返回當前請求中名為 XXX 的請求頭

  需要注意的是, $http_XXX 變量在匹配請求頭時會自動對請求頭的名字進行歸一化,即將名字的大寫字母轉換為小寫字母,同時把間隔符(-)替換為下划線(_)

3、輸出過濾器

  ngx_echo模塊的echo_before_body和echo_after_body

  Nginx 在輸出響應體數據時都會調用“輸出過濾器”,不屬於某個階段,只要有輸出響應,就會調用輸出過濾器。

4、外部跳轉

  302 和 301 響應的“外部跳轉”,瀏覽器地址發生變化。

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM