主頁 > 作業系統 > 關于Nginx處理HTTP請求的11個階段流程

關于Nginx處理HTTP請求的11個階段流程

2020-09-20 06:24:49 作業系統

nginx實際把http請求處理流程劃分為了11個階段,這樣劃分的原因是將請求的執行邏輯細分,以模塊為單位進行處理,各個階段可以包含任意多個http模塊并以流水線的方式處理請求,這樣做的好處是使處理程序更加靈活、降低耦合度,可以讓每個HTTP模塊可以僅僅專注于完成一個獨立,簡單的功能,而一個請求的完整處理程序可以由多個HTTP模塊共同合作完成,可以極大的提高多個模塊合作的協同性,可測驗性,可擴展性,換言之,nginx在處理每一個http請求,和組態檔上的順序沒有關系,這11個http階段如下所示:

1)ngx_http_post_read_phase:

接收到完整的http頭部后處理的階段,它位于uri重寫之前,實際上很少有模塊會注冊在該階段,默認的情況下,該階段被跳過,

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

2)ngx_http_server_rewrite_phase:

uri與location匹配前,修改uri的階段,用于重定向,也就是該階段執行處于server塊內,location塊外的重寫指令,在讀取請求頭的程序中nginx會根據host及埠找到對應的虛擬主機配置,

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

3)ngx_http_find_config_phase:

根據uri尋找匹配的location塊配置項階段,該階段使用重寫之后的uri來查找對應的location,值得注意的是該階段可能會被執行多次,因為也可能有location級別的重寫指令,

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

4)ngx_http_rewrite_phase:

上一階段找到location塊后再修改uri,location級別的uri重寫階段,該階段執行location基本的重寫指令,也可能會被執行多次,

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

5)ngx_http_post_rewrite_phase:

防止重寫url后導致的死回圈,location級別重寫的后一階段,用來檢查上階段是否有uri重寫,并根據結果跳轉到合適的階段,

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

6)ngx_http_preaccess_phase:

下一階段之前的準備,訪問權限控制的前一階段,該階段在權限控制階段之前,一般也用于訪問控制,比如限制訪問頻率,鏈接數等,

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

7)ngx_http_access_phase:

讓http模塊判斷是否允許這個請求進入nginx服務器,訪問權限控制階段,比如基于ip黑白名單的權限控制,基于用戶名密碼的權限控制等,

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

8)ngx_http_post_access_phase:

訪問權限控制的后一階段,該階段根據權限控制階段的執行結果進行相應處理,向用戶發送拒絕服務的錯誤碼,用來回應上一階段的拒絕,

這個階段也和 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)ngx_http_try_files_phase:

為訪問靜態檔案資源而設定,try_files指令的處理階段,如果沒有配置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)ngx_http_content_phase:

處理http請求內容的階段,大部分http模塊介入這個階段,內容生成階段,該階段產生回應,并發送到客戶端,

Nginx 的 content 階段是所有請求處理階段中最為重要的一個,因為運行在這個階段的配置指令一般都肩負著生成“內容”(content)并輸出 HTTP 回應的使命,正因為其重要性,這個階段的配置指令也例外豐富,如echo、 echo_exec 指令, proxy_pass 指令, echo_location 指令,content_by_lua,

11)ngx_http_log_phase:

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

處理完請求后的日志記錄階段,該階段記錄訪問日志,

以上11個階段中,http無法介入的階段有4個:

3)ngx_http_find_config_phase

5)ngx_http_post_rewrite_phase

8)ngx_http_post_access_phase

9)ngx_http_try_files_phase

剩余的7個階段,http模塊均能介入,每個階段可介入模塊的個數也是沒有限制的,多個http模塊可同時介入同一階段并作用于同一請求,

 

 

參考博客:https://www.cnblogs.com/zhenyuyaodidiao/p/9288430.html

https://www.cnblogs.com/vinsent/p/12259287.html

 


 

轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/86600.html

標籤:Linux

上一篇:防火墻(firewall)的操作命令

下一篇:應用系統分布式構建運維

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • CA和證書

    1、在 CentOS7 中使用 gpg 創建 RSA 非對稱密鑰對 gpg --gen-key #Centos上生成公鑰/密鑰對(存放在家目錄.gnupg/) 2、將 CentOS7 匯出的公鑰,拷貝到 CentOS8 中,在 CentOS8 中使用 CentOS7 的公鑰加密一個檔案 gpg -a ......

    uj5u.com 2020-09-10 00:09:53 more
  • Kubernetes K8S之資源控制器Job和CronJob詳解

    Kubernetes的資源控制器Job和CronJob詳解與示例 ......

    uj5u.com 2020-09-10 00:10:45 more
  • VMware下安裝CentOS

    VMware下安裝CentOS 一、軟硬體準備 1 Centos鏡像準備 1.1 CentOS鏡像下載地址 下載地址 1.2 CentOS鏡像下載程序 點擊下載地址進入如下圖的網站,選擇需要下載的版本,這里選擇的是Centos8,點擊如圖所示。 決定選擇Centos8后,選擇想要的鏡像源進行下載,此 ......

    uj5u.com 2020-09-10 00:12:10 more
  • 如何使用Grep命令查找多個字串

    如何使用Grep 命令查找多個字串 大家好,我是良許! 今天向大家介紹一個非常有用的技巧,那就是使用 grep 命令查找多個字串。 簡單介紹一下,grep 命令可以理解為是一個功能強大的命令列工具,可以用它在一個或多個輸入檔案中搜索與正則運算式相匹配的文本,然后再將每個匹配的文本用標準輸出的格式 ......

    uj5u.com 2020-09-10 00:12:28 more
  • git配置http代理

    git配置http代理 經常遇到克隆 github 慢的問題,這里記錄一下幾種配置 git 代理的方法,解決 clone github 過慢。 目錄 git配置代理 git單獨配置github代理 git配置全域代理 配置終端環境變數 git配置代理 主要使用 git config 命令 git單獨 ......

    uj5u.com 2020-09-10 00:12:33 more
  • Linux npm install 裝包時提示Error EACCES permission denied解

    npm install 裝包時提示Error EACCES permission denied解決辦法 ......

    uj5u.com 2020-09-10 00:12:53 more
  • Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包

    Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包。 18 (flaskApi) [root@67 flaskDemo]# yum -y install nginx 19 已加載插件:fastestmirror, langpacks 20 Loading ......

    uj5u.com 2020-09-10 00:13:13 more
  • Linux查看服務器暴力破解ssh IP

    在公網的服務器上經常遇到別人爆破你服務器的22埠,用來挖礦或者干其他嘿嘿嘿的事情~ 這種情況下正確的做法是: 修改默認ssh的22埠 使用設定密鑰登錄或者白名單ip登錄 建議服務器密碼為復雜密碼 創建普通用戶登錄服務器(root權限過大) 建立堡壘機,實作統一管理服務器 統計爆破IP [root ......

    uj5u.com 2020-09-10 00:13:17 more
  • CentOS 7系統常見快捷鍵操作方式

    Linux系統中一些常見的快捷方式,可有效提高操作效率,在某些時刻也能避免操作失誤帶來的問題。 ......

    uj5u.com 2020-09-10 00:13:31 more
  • CentOS 7作業系統目錄結構介紹

    作業系統存在著大量的資料檔案資訊,相應檔案資訊會存在于系統相應目錄中,為了更好的管理資料資訊,會將系統進行一些目錄規劃,不同目錄存放不同的資源。 ......

    uj5u.com 2020-09-10 00:13:35 more
最新发布
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:43:21 more
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:42:36 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:26:53 more
  • 設定Windows主機的瀏覽器為wls2的默認瀏覽器

    這里以Chrome為例。 1. 準備作業 wsl是可以使用Windows主機上安裝的exe程式,出于安全考慮,默認情況下改功能是無法使用。要使用的話,終端需要以管理員權限啟動。 我這里以Windows Terminal為例,介紹如何默認使用管理員權限打開終端,具體操作如下圖所示: 2. 操作 wsl ......

    uj5u.com 2023-04-19 09:25:49 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:19:04 more
  • Linux學習筆記

    IP地址和主機名 IP地址 ifconfig可以用來查詢本機的IP地址,如果不能使用,可以通過install net-tools安裝。 Centos系統下ens33表示主網卡;inet后表示IP地址;lo表示本地回環網卡; 127.0.0.1表示代指本機;0.0.0.0可以用于代指本機,同時在放行設 ......

    uj5u.com 2023-04-18 06:52:01 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:50 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:01 more
  • 你是不是暴露了?

    作者:袁首京 原創文章,轉載時請保留此宣告,并給出原文連接。 如果您是計算機相關從業人員,那么應該經歷不止一次網路安全專項檢查了,你肯定是收到過資訊系統技術檢測報告,要求你加強風險監測,確保你提供的系統服務堅實可靠了。 沒檢測到問題還好,檢測到問題的話,有些處理起來還是挺麻煩的,尤其是線上正在運行的 ......

    uj5u.com 2023-04-05 16:52:56 more
  • 細節拉滿,80 張圖帶你一步一步推演 slab 記憶體池的設計與實作

    1. 前文回顧 在之前的幾篇記憶體管理系列文章中,筆者帶大家從宏觀角度完整地梳理了一遍 Linux 記憶體分配的整個鏈路,本文的主題依然是記憶體分配,這一次我們會從微觀的角度來探秘一下 Linux 內核中用于零散小記憶體塊分配的記憶體池 —— slab 分配器。 在本小節中,筆者還是按照以往的風格先帶大家簡單 ......

    uj5u.com 2023-04-05 16:44:11 more