讀取完請求頭后,nginx進入請求的處理階段。簡單的情況下,客戶端發送過的統一資源定位符(url)對應服務器上某一路徑上的資源,web服務器需要做的僅僅是將url映射到本地文件系統的路徑,然后讀取相應文件并返回給客戶端。但這僅僅是最初的互聯網的需求,而如今互聯網出現了各種各樣復雜的需求,要求web服務器能夠處理諸如安全及權限控制,多媒體內容和動態網頁等等問題。這些復雜的需求導致web服務器不再是一個短小的程序,而變成了一個必須經過仔細設計,模塊化的系統。nginx良好的模塊化特性體現在其對請求處理流程的多階段劃分當中,多階段處理流程就好像一條流水線,一個nginx進程可以并發的處理處于不同階段的多個請求。nginx允許開發者在處理流程的任意階段注冊模塊,在啟動階段,nginx會把各個階段注冊的所有模塊處理函數按序的組織成一條執行鏈。
nginx實際把請求處理流程劃分為了11個階段,這樣劃分的原因是將請求的執行邏輯細分,各階段按照處理時機定義了清晰的執行語義,開發者可以很容易分辨自己需要開發的模塊應該定義在什么階段,下面介紹一下各階段:
<table class="docutils field-list" frame="void" rules="none" style="margin: 0px -0.5em; border: 0px; color: rgb(0, 0, 0); font-family: 'segoe UI', sans-serif; letter-spacing: -0.1599999964237213px; line-height: 24px; white-space: normal; background-color: rgb(255, 255, 255);"><colgroup><col class="field-name"/><col class="field-body"/></colgroup><tbody valign="top"><tr class="field-odd field"><th class="field-name" colspan="2" style="padding: 1px 8px 1px 5px; border: 0px !important;">NGX_HTTP_POST_READ_PHASE:</th></tr><tr class="field-odd field"><td style="padding: 1px 8px 1px 5px; border: 0px !important;">?</td><td class="field-body" style="padding: 1px 8px 1px 5px; border: 0px !important;">接收完請求頭之后的第一個階段,它位于uri重寫之前,實際上很少有模塊會注冊在該階段,默認的情況下,該階段被跳過;</td></tr><tr class="field-even field"><th class="field-name" colspan="2" style="padding: 1px 8px 1px 5px; border: 0px !important;">NGX_HTTP_SERVER_REWRITE_PHASE:</th></tr><tr class="field-even field"><td style="padding: 1px 8px 1px 5px; border: 0px !important;">?</td><td class="field-body" style="padding: 1px 8px 1px 5px; border: 0px !important;">server級別的uri重寫階段,也就是該階段執行處于server塊內,location塊外的重寫指令,前面的章節已經說明在讀取請求頭的過程中nginx會根據host及端口找到對應的虛擬主機配置;</td></tr><tr class="field-odd field"><th class="field-name" colspan="2" style="padding: 1px 8px 1px 5px; border: 0px !important;">NGX_HTTP_FIND_CONFIG_PHASE:</th></tr><tr class="field-odd field"><td style="padding: 1px 8px 1px 5px; border: 0px !important;">?</td><td class="field-body" style="padding: 1px 8px 1px 5px; border: 0px !important;">尋找location配置階段,該階段使用重寫之后的uri來查找對應的location,值得注意的是該階段可能會被執行多次,因為也可能有location級別的重寫指令;</td></tr><tr class="field-even field"><th class="field-name" colspan="2" style="padding: 1px 8px 1px 5px; border: 0px !important;">NGX_HTTP_REWRITE_PHASE:</th></tr><tr class="field-even field"><td style="padding: 1px 8px 1px 5px; border: 0px !important;">?</td><td class="field-body" style="padding: 1px 8px 1px 5px; border: 0px !important;">location級別的uri重寫階段,該階段執行location基本的重寫指令,也可能會被執行多次;</td></tr><tr class="field-odd field"><th class="field-name" colspan="2" style="padding: 1px 8px 1px 5px; border: 0px !important;">NGX_HTTP_POST_REWRITE_PHASE:</th></tr><tr class="field-odd field"><td style="padding: 1px 8px 1px 5px; border: 0px !important;">?</td><td class="field-body" style="padding: 1px 8px 1px 5px; border: 0px !important;">location級別重寫的后一階段,用來檢查上階段是否有uri重寫,并根據結果跳轉到合適的階段;</td></tr><tr class="field-even field"><th class="field-name" colspan="2" style="padding: 1px 8px 1px 5px; border: 0px !important;">NGX_HTTP_PREACCESS_PHASE:</th></tr><tr class="field-even field"><td style="padding: 1px 8px 1px 5px; border: 0px !important;">?</td><td class="field-body" style="padding: 1px 8px 1px 5px; border: 0px !important;">訪問權限控制的前一階段,該階段在權限控制階段之前,一般也用于訪問控制,比如限制訪問頻率,鏈接數等;</td></tr><tr class="field-odd field"><th class="field-name" colspan="2" style="padding: 1px 8px 1px 5px; border: 0px !important;">NGX_HTTP_ACCESS_PHASE:</th></tr><tr class="field-odd field"><td style="padding: 1px 8px 1px 5px; border: 0px !important;">?</td><td class="field-body" style="padding: 1px 8px 1px 5px; border: 0px !important;">訪問權限控制階段,比如基于ip黑白名單的權限控制,基于用戶名密碼的權限控制等;</td></tr><tr class="field-even field"><th class="field-name" colspan="2" style="padding: 1px 8px 1px 5px; border: 0px !important;">NGX_HTTP_POST_ACCESS_PHASE:</th></tr><tr class="field-even field"><td style="padding: 1px 8px 1px 5px; border: 0px !important;">?</td><td class="field-body" style="padding: 1px 8px 1px 5px; border: 0px !important;">訪問權限控制的后一階段,該階段根據權限控制階段的執行結果進行相應處理;</td></tr><tr class="field-odd field"><th class="field-name" colspan="2" style="padding: 1px 8px 1px 5px; border: 0px !important;">NGX_HTTP_TRY_FILES_PHASE:</th></tr><tr class="field-odd field"><td style="padding: 1px 8px 1px 5px; border: 0px !important;">?</td><td class="field-body" style="padding: 1px 8px 1px 5px; border: 0px !important;">try_files指令的處理階段,如果沒有配置try_files指令,則該階段被跳過;</td></tr><tr class="field-even field"><th class="field-name" colspan="2" style="padding: 1px 8px 1px 5px; border: 0px !important;">NGX_HTTP_CONTENT_PHASE:</th></tr><tr class="field-even field"><td style="padding: 1px 8px 1px 5px; border: 0px !important;">?</td><td class="field-body" style="padding: 1px 8px 1px 5px; border: 0px !important;">內容生成階段,該階段產生響應,并發送到客戶端;</td></tr><tr class="field-odd field"><th class="field-name" colspan="2" style="padding: 1px 8px 1px 5px; border: 0px !important;">NGX_HTTP_LOG_PHASE:</th></tr><tr class="field-odd field"><td style="padding: 1px 8px 1px 5px; border: 0px !important;">?</td><td class="field-body" style="padding: 1px 8px 1px 5px; border: 0px !important;">日志記錄階段,該階段記錄訪問日志。</td></tr></tbody></table>
- 上篇:nginx模塊開發篇
- nginx平臺初探
- 初探nginx架構
- nginx基礎概念
- connection
- request
- keepalive
- pipe
- lingering_close
- 基本數據結構
- ngx_str_t
- ngx_pool_t
- ngx_array_t
- ngx_hash_t
- ngx_hash_wildcard_t
- ngx_hash_combined_t
- ngx_hash_keys_arrays_t
- ngx_chain_t
- ngx_buf_t
- ngx_list_t
- ngx_queue_t
- nginx的配置系統
- 指令參數
- 指令上下文
- nginx的模塊化體系結構
- 模塊的分類
- nginx的請求處理
- handler模塊
- handler模塊簡介
- 模塊的基本結構
- 模塊配置結構
- 模塊配置指令
- 模塊上下文結構
- 模塊的定義
- handler模塊的基本結構
- handler模塊的掛載
- handler的編寫步驟
- 示例: hello handler 模塊
- handler模塊的編譯和使用
- 更多handler模塊示例分析
- http access module
- http static module
- http log module
- 過濾模塊
- 過濾模塊簡介
- 過濾模塊的分析
- upstream模塊
- upstream模塊
- upstream模塊接口
- memcached模塊分析
- 本節回顧
- 負載均衡模塊
- 配置
- 指令
- 鉤子
- 初始化配置
- 初始化請求
- peer.get和peer.free回調函數
- 本節回顧
- 其他模塊
- core模塊
- event模塊
- 模塊開發高級篇
- 變量
- 下篇:nginx原理解析篇
- nginx架構詳解
- nginx的源碼目錄結構
- nginx的configure原理
- 模塊編譯順序
- nginx基礎設施
- 內存池
- nginx的啟動階段
- 概述
- 共有流程
- 配置解析
- nginx的請求處理階段
- 接收請求流程
- http請求格式簡介
- 請求頭讀取
- 解析請求行
- 解析請求頭
- 請求體讀取
- 讀取請求體
- 丟棄請求體
- 多階段處理請求
- 多階段執行鏈
- POST_READ階段
- SERVER_REWRITE階段
- FIND_CONFIG階段
- REWRITE階段
- POST_REWRITE階段
- PREACCESS階段
- ACCESS階段
- POST_ACCESS階段
- TRY_FILES階段
- CONTENT階段
- LOG階段
- Nginx filter
- header filter分析
- body filter分析
- ngx_http_copy_filter_module分析
- ngx_http_write_filter_module分析
- subrequest原理解析
- https請求處理解析
- 附錄A 編碼風格
- 附錄B 常用API
- 附錄C 模塊編譯,調試與測試