注冊用戶即可下載全站資源 關注Java幫幫微信公眾號
 

Nginx請求處理流程你了解嗎?

24
發表時間:2018-12-22 12:44

本文主要介紹了nginx的11個處理階段和lua的8個處理階段,并說明了nginx和lua運行階段的對應關系。

一、nginx 11 個處理階段

日本韩国三级aⅴ在线观看nginx實際把http請求處理流程劃分為了11個階段,這樣劃分的原因是將請求的執行邏輯細分,以模塊為單位進行處理,各個階段可以包含任意多個HTTP模塊并以流水線的方式處理請求。這樣做的好處是使處理過程更加靈活、降低耦合度。這11個HTTP階段如下所示:

1)NGX_HTTP_POST_READ_PHASE:

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

2)NGX_HTTP_SERVER_REWRITE_PHASE:

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

3)NGX_HTTP_FIND_CONFIG_PHASE:

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

4)NGX_HTTP_REWRITE_PHASE:

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

5)NGX_HTTP_POST_REWRITE_PHASE:

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

6)NGX_HTTP_PREACCESS_PHASE:

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

7)NGX_HTTP_ACCESS_PHASE:

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

8)NGX_HTTP_POST_ACCESS_PHASE:

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

9)NGX_HTTP_TRY_FILES_PHASE:

為訪問靜態文件資源而設置,try_files指令的處理階段,如果沒有配置try_files指令,則該階段被跳過。

10)NGX_HTTP_CONTENT_PHASE:

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

11)NGX_HTTP_LOG_PHASE:

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

以上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模塊可同時介入同一階段并作用于同一請求。

HTTP階段的定義,包括checker檢查方法和handler處理方法,如下所示

一個http{}塊解析完畢后,將會根據nginx.conf中的配置產生由ngx_http_phase_handler_t組成的數組,在處理HTTP請求時,一般情況下這些階段是順序向后執行的,但ngx_http_phase_handler_t中的next成員使得它們也可以非順序地執行,ngx_http_phase_engine_t結構體就是所有ngx_http_phase_handler_t組成的數組,如下所示:

日本韩国三级aⅴ在线观看可以看到,ngx_http_phase_engine_t中保存了在當前nginx.conf配置下,一個用戶請求可能經歷的所有ngx_http_handler_pt處理方法,這是所有HTTP模塊可以合作處理用戶請求的關鍵,這個ngx_http_phase_engine_t結構體保存在全局的ngx_http_core_main_conf_t結構體中,如下:

在ngx_http_phase_t中關于HTTP階段有兩個成員:phase_engine和phases,其中phase_engine控制運行過程中的一個HTTP請求所要經過的HTTP處理階段,它將配合ngx_http_request_t結構體中的phase_handler成員使用(phase_handler制定了當前請求應當執行哪一個HTTP階段);而phases數組更像一個臨時變量,它實際上僅會在Nginx啟動過程中用到,它的唯一使命是按照11個階段的概率初始化phase_engine中的handlers數組。

日本韩国三级aⅴ在线观看在HTTP框架的初始化過程中,任何HTTP模塊都可以在ngx_http_module_t接口的postconfiguration方法中將自定義的方法添加到handler動態數組中,這樣,這個方法就會最終添加到phase_engine動態數組中。

二、nginx lua 8個階段

1)init_by_lua:

日本韩国三级aⅴ在线观看在nginx重新加載配置文件時,運行里面lua腳本,常用于全局變量的申請。(例如:lua_shared_dict共享內存的申請,只有當nginx重起后,共享內存數據才清空,這常用于統計。)

2)set_by_lua:

日本韩国三级aⅴ在线观看流程分支處理判斷變量初始化(設置一個變量,常用與計算一個邏輯,然后返回結果,該階段不能運行Output API、Control API、Subrequest API、Cosocket API)

3)rewrite_by_lua:

轉發、重定向、緩存等功能 (例如特定請求代理到外網,在access階段前運行,主要用于rewrite)

4)access_by_lua:

IP準入、接口權限等情況集中處理(例如配合iptable完成簡單防火墻,主要用于訪問控制,能收集到大部分變量,類似status日本韩国三级aⅴ在线观看需要在log階段才有。這條指令運行于nginx access階段的末尾,因此總是在 allow 和 deny 這樣的指令之后運行,雖然它們同屬 access 階段。)

5)content_by_lua:

內容生成,階段是所有請求處理階段中最為重要的一個,運行在這個階段的配置指令一般都肩負著生成內容(content)并輸出HTTP響應。

6)header_filter_by_lua:

應答HTTP過濾處理,一般只用于設置Cookie日本韩国三级aⅴ在线观看和Headers等,該階段不能運行Output API、Control API、Subrequest API、Cosocket API(例如添加頭部信息)。

7)body_filter_by_lua:

應答BODY過濾處理(例如完成應答內容統一成大寫)(一般會在一次請求中被調用多次, 因為這是實現基于 HTTP 1.1 chunked 編碼的所謂“流式輸出”的,該階段不能運行Output API、Control API、Subrequest API、Cosocket API)

8)log_by_lua:

會話完成后本地異步完成日志記錄(日志可以記錄在本地,還可以同步到其他機器)(該階段總是運行在請求結束的時候,用于請求的后續操作,如在共享內存中進行統計數據,如果要高精確的數據統計,應該使用body_filter_by_lua,該階段不能運行Output API、Control API、Subrequest API、Cosocket API)

三、nginx和lua運行階段的對應關系

日本韩国三级aⅴ在线观看1)init_by_lua,運行在initialization Phase;

2)set_by_lua,運行在rewrite 階段;

set 指令來自 ngx_rewrite 模塊,運行于 rewrite 階段;

3)rewrite_by_lua 指令來自 ngx_lua 模塊,運行于 rewrite 階段的末尾

日本韩国三级aⅴ在线观看4)access_by_lua 指令同樣來自 ngx_lua 模塊,運行于 access 階段的末尾;

deny 指令來自 ngx_access 模塊,運行于 access 階段;

日本韩国三级aⅴ在线观看5)content_by_lua 指令來自 ngx_lua 模塊,運行于 content 階段;不要將它和其它的內容處理指令在同一個location內使用如proxy_pass;

echo 指令則來自 ngx_echo 模塊,運行在 content 階段;

6)header_filter_by_lua 運行于 content 階段,output-header-filter 一般用來設置cookie和headers;

7)body_filter_by_lua,運行于 content 階段;

8)log_by_lua,運行在Log Phase 階段;

如圖:


支付寶贊助-Java幫幫社區
微信贊助-Java幫幫社區
Java幫幫公眾號生態

Java幫幫公眾號生態

總有一款適合你

Java幫幫-微信公眾號

Java幫幫-微信公眾號

將分享做到極致

Python幫幫-公眾號

Python幫幫-公眾號

人工智能,爬蟲,學習教程

大數據驛站-微信公眾號

大數據驛站-微信公眾號

一起在數據中成長

九點編程-公眾號

九點編程-公眾號

深夜九點學編程

程序員生活志-公眾號

程序員生活志-公眾號

互聯網,職場,程序員那些事兒

Java幫幫學習群生態

Java幫幫學習群生態

總有一款能幫到你

Java學習群

Java學習群

與大牛一起交流

大數據學習群

大數據學習群

在數據中成長

九點編程學習群

九點編程學習群

深夜九點學編程

python學習群

python學習群

人工智能,爬蟲

測試學習群

測試學習群

感受測試的魅力

Java幫幫生態承諾

Java幫幫生態承諾

一直堅守,不負重望

初心
勤儉
誠信
正義
分享
合作品牌 非盈利生態-優質內容分享傳播者
關于我們
友鏈申請
友鏈交換:加幫主QQ2524138991 留言即可 24小時內答復  
全站內容非商業用途,內容來源于網友,并遵循 許可,如有異議請聯系客服。
會員登錄
獲取驗證碼
登錄
登錄
我的資料
留言
回到頂部