Nginx處理請求的11個階段(agentzh的Nginx 教程學習記錄)


Nginx 處理請求的過程一共划分為 11 個階段,按照執行順序依次是 post-read、server-rewrite、find-config、rewrite、post-rewrite、preaccess、access、post-access、try-files、content 以及 log。

1、post-read

最先執行的 post-read 階段在 Nginx 讀取並解析完請求頭(request headers)之后就立即開始運行。例如:使用了  ngx_realip 模塊提供的  set_real_ip_from 和  real_ip_header 這兩條配置指令

2、server-rewrite

由於 server-rewrite 階段位於 post-read 階段之后,所以 server 配置塊中的  set 指令也就總是運行在  ngx_realip 模塊改寫請求的來源地址之后。

3、find-config

這個階段並不支持 Nginx 模塊注冊處理程序,而是由 Nginx 核心來完成當前請求與 location 配置塊之間的配對工作。換句話說,在此階段之前,請求並沒有與任何 location 配置塊相關聯。因此,對於運行在 find-config 階段之前的 post-read 和 server-rewrite 階段來說,只有 server 配置塊以及更外層作用域中的配置指令才會起作用。這就是為什么只有寫在 server 配置塊中的  ngx_rewrite 模塊的指令才會運行在 server-rewrite 階段,這也是為什么前面所有例子中的  ngx_realip 模塊的指令也都特意寫在了 server 配置塊中,以確保其注冊在 post-read 階段的處理程序能夠生效。

4、rewrite

由於 Nginx 已經在 find-config 階段完成了當前請求與 location 的配對,所以從 rewrite 階段開始,location 配置塊中的指令便可以產生作用。當  ngx_rewrite 模塊的指令用於 location 塊中時,便是運行在這個 rewrite 階段。

5、post-rewrite

這個階段也像 find-config 階段那樣不接受 Nginx 模塊注冊處理程序,而是由 Nginx 核心完成 rewrite 階段所要求的“內部跳轉”操作(如果 rewrite 階段有此要求的話)。例如:通過  rewrite 指令把當前請求的 URI 無條件地改寫為 /bar,同時發起一個“內部跳轉”,最終跳進了 location /bar 中。這里比較有趣的地方是“內部跳轉”的工作原理。“內部跳轉”本質上其實就是把當前的請求處理階段強行倒退到 find-config 階段,以便重新進行請求 URI 與 location 配置塊的配對。

6、preaccess

該階段在 access 階段之前執行,故名 preaccess.標准模塊  ngx_limit_req 和  ngx_limit_zone 就運行在此階段,前者可以控制請求的訪問頻度,而后者可以限制訪問的並發度。

7、access

標准模塊  ngx_access、第三方模塊  ngx_auth_request 以及第三方模塊  ngx_lua 的  access_by_lua 指令就運行在這個階段。

8、 post-access

這個階段也和 post-rewrite 階段類似,並不支持 Nginx 模塊注冊處理程序,而是由 Nginx 核心自己完成一些處理工作。post-access 階段主要用於配合 access 階段實現標准  ngx_http_core 模塊提供的配置指令  satisfy 的功能。對於多個 Nginx 模塊注冊在 access 階段的處理程序,  satisfy 配置指令可以用於控制它們彼此之間的協作方式。比如模塊 A 和 B 都在 access 階段注冊了與訪問控制相關的處理程序,那就有兩種協作方式,一是模塊 A 和模塊 B 都得通過驗證才算通過,二是模塊 A 和模塊 B 只要其中任一個通過驗證就算通過。第一種協作方式稱為 all 方式(或者說“與關系”),第二種方式則被稱為 any 方式(或者說“或關系”)。默認情況下,Nginx 使用的是 all 方式。

9、try-files

這個階段專門用於實現標准配置指令  try_files 的功能,並不支持 Nginx 模塊注冊處理程序。 try_files 指令接受兩個以上任意數量的參數,每個參數都指定了一個 URI. 這里假設配置了 N 個參數,則 Nginx 會在 try-files 階段,依次把前 N-1 個參數映射為文件系統上的對象(文件或者目錄),然后檢查這些對象是否存在。一旦 Nginx 發現某個文件系統對象存在,就會在 try-files 階段把當前請求的 URI 改寫為該對象所對應的參數 URI(但不會包含末尾的斜杠字符,也不會發生 “內部跳轉”)。如果前 N-1 個參數所對應的文件系統對象都不存在,try-files 階段就會立即發起“內部跳轉”到最后一個參數(即第 N 個參數)所指定的 URI.通過  root 配置指令所指定的“文檔根目錄”進行映射。例如,當“文檔根目錄”是 /var/www/ 的時候,請求 URI /foo/bar 會被映射為文件 /var/www/foo/bar,而請求 URI /foo/baz/ 則會被映射為目錄 /var/www/foo/baz/. 注意這里是如何通過 URI 末尾的斜杠字符是否存在來區分“目錄”和“文件”的。

10、content

Nginx 的 content 階段是所有請求處理階段中最為重要的一個,因為運行在這個階段的配置指令一般都肩負着生成“內容”(content)並輸出 HTTP 響應的使命。正因為其重要性,這個階段的配置指令也異常豐富。echo、  Nginx 變量漫談(二) 中接觸到的  echo_exec 指令,  Nginx 變量漫談(三) 中接觸到的  proxy_pass 指令, Nginx 變量漫談(五) 中介紹過的  echo_location 指令,以及  Nginx 變量漫談(七) 中介紹過的  content_by_lua

11、log

log階段處理,比如記錄訪問量/統計平均響應時間。log_by_lua
 


免責聲明!

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



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