今天我們講 request,在 Nginx 中我們指的是 http 請求,具體到 Nginx 中的資料結構是ngx_http_request_t。 ngx_http_request_t 是對一個 http 請求的封裝。我們知道,一個 http 請求,包含請求行、請求頭、請求體、回應行、回應頭、回應體。
http 請求是典型的請求-回應類型的網路協議,而http 是文字協議,所以我們在分析請求行與請求頭,以及輸出回應行與回應頭,往往是一行一行的進行處理。 ( 建議學習:nginx使用 )
如果我們自己來寫一個 http 伺服器,通常在一個連線建立好後,客戶端會發送請求過來。然後我們讀取一行數據,分析出請求行中包含的 method、uri、http_version 資訊。
然後再一行一行處理請求頭,並根據請求 method 與請求頭的資訊來決定是否有請求體以及請求體的長度,然後再去讀取請求體。
得到請求後,我們處理請求產生需要輸出的數據,然後再產生回應行,回應頭以及回應體。
在將回應傳送給客戶端之後,一個完整的請求就處理完了。當然這是最簡單的 webserver 的處理方式,其實 Nginx 也是這樣做的,只是有一些小小的區別,比如,當請求頭讀取完成後,就開始進行請求的處理了。 Nginx 透過 ngx_http_request_t 來保存解析請求與輸出回應相關的資料。
那接下來,簡單講講 Nginx 是如何處理一個完整的請求的。 對於 Nginx 來說,一個請求是從ngx_http_init_request 開始的,在這個函數中,會設定讀取事件為 ngx_http_process_request_line,也就是說,接下來的網路事件,會由 ngx_http_process_request_line 來執行。
從ngx_http_process_request_line 的函數名,我們可以看到,這就是來處理請求行的,正好與之前講的,處理請求的第一件事就是處理請求行是一致的。
透過 ngx_http_read_request_header 來讀取請求資料。然後呼叫 ngx_http_parse_request_line 函數來解析請求行。 Nginx 為提高效率,採用狀態機來解析請求行,而且在進行method 的比較時,沒有直接使用字串比較,而是將四個字元轉換成一個整數,然後一次比較以減少cpu 的指令數,這個前面有說過。
很多人可能很清楚一個請求行包含請求的方法,uri,版本,卻不知道其實在請求行中,也是可以包含有 host 的。例如一個請求GET http://www.taobao.com/uri HTTP/1.0 這樣一個請求行也是合法的,而且host 是www.taobao.com,這個時候,Nginx 會忽略請求頭中的host 域,而以請求行中的這個為準來查找虛擬主機。
另外,對於 http0.9 版來說,是不支援請求頭的,所以這裡也是要特別的處理。所以,在後面解析請求頭時,協定版本都是 1.0 或 1.1。整個請求行解析到的參數,會儲存到 ngx_http_request_t 結構當中。
在解析完請求行後,Nginx 會設定讀取事件的 handler 為 ngx_http_process_request_headers,然後後續的請求就在 ngx_http_process_request_headers 中進行讀取與解析。
ngx_http_process_request_headers 函數用來讀取請求頭,跟請求行一樣,還是呼叫ngx_http_read_request_header 來讀取請求頭,呼叫ngx_http_parse_header_line 來解析一行請求頭,解析到的請求頭會保存到ngx_http_request_in 的域中,headers_in 是一個鍊錶結構,保存所有的請求頭。
而HTTP 中有些請求是需要特別處理的,這些請求頭與請求處理函數存放在一個映射表裡面,即ngx_http_headers_in,在初始化時,會產生一個hash 表,當每解析到一個請求頭後,就會先在這個hash 表中查找,如果有找到,則呼叫對應的處理函數來處理這個請求頭。例如:Host 頭的處理函數是 ngx_http_process_host。
當 Nginx 解析到兩個回車換行符時,就表示請求頭的結束,此時就會呼叫 ngx_http_process_request 來處理請求了。
ngx_http_process_request 會設定目前的連線的讀寫事件處理函式為 ngx_http_request_handler,然後再呼叫 ngx_http_handler 來真正開始處理一個完整的http請求。
這裡可能比較奇怪,讀寫事件處理函式都是ngx_http_request_handler,其實在這個函式中,會根據目前事件是讀取事件還是寫事件,分別呼叫 ngx_http_request_t 中的 read_event_handler 或是 write_event_handler。
由於此時,我們的請求頭已經讀取完成了,之前有說過,Nginx 的做法是先不讀取請求body,所以這裡面我們設定read_event_handler 為ngx_http_block_reading,即不讀取數據了。
剛才說到,真正開始處理數據,是在 ngx_http_handler 這個函數裡面,這個函數會設定 write_event_handler 為 ngx_http_core_run_phases,並執行 ngx_http_core_run_phases 函數。
ngx_http_core_run_phases 這個函數會執行多階段請求處理,Nginx 將一個 http 請求的處理分成多個階段,那麼這個函數就是執行這些階段來產生資料。
因為 ngx_http_core_run_phases 最後會產生數據,所以我們就很容易理解,為什麼設定寫事件的處理函數為 ngx_http_core_run_phases 了。
在這裡,我簡單說明了一下函數的呼叫邏輯,我們需要明白最終是呼叫ngx_http_core_run_phases 來處理請求,產生的回應頭會放在ngx_http_request_t 的headers_out 中,這一部分內容,我會放在請求處理流程裡面去講。 Nginx 的各種階段會對請求進行處理,最後會呼叫 filter 來過濾數據,對數據進行加工,如 truncked 傳輸、gzip 壓縮等。
這裡的 filter 包含 header filter 與 body filter,即對回應頭或回應體進行處理。 filter 是鍊錶結構,分別有 header filter 與 body filter,先執行 header filter 中的所有 filter,然後再執行 body filter 中的所有 filter。
在 header filter 中的最後一個 filter,即 ngx_http_header_filter,這個 filter 將會遍歷所有的響應頭,最後需要輸出的響應頭在一個連續的內存,然後調用 ngx_http_write_filter 進行輸出。
ngx_http_write_filter 是 body filter 中的最後一個,所以 Nginx 首先的 body 訊息,在經過一系列的 body filter 之後,最後也會呼叫 ngx_http_write_filter 來進行輸出(有圖來說明)。
這裡要注意的是,Nginx 會將整個請求頭都放在一個buffer 裡面,這個buffer 的大小透過設定項client_header_buffer_size 來設置,如果使用者的請求頭太大,這個buffer 裝不下,那Nginx 就會重新分配一個新的更大的buffer 來裝請求頭,這個大buffer 可以透過large_client_header_buffers 來設置,這個large_buffer 這一組buffer,例如配置48k,就是表示有四個8k 大小的buffer 可以用。
注意,為了保存請求行或請求頭的完整性,一個完整的請求行或請求頭,需要放在一個連續的記憶體裡面,所以,一個完整的請求行或請求頭,只會保存在一個buffer 裡面。
這樣,如果請求行大於一個 buffer 的大小,就會回傳 414 錯誤,如果一個請求頭大小大於一個 buffer 大小,就會回傳 400 錯誤。在了解了這些參數的值,以及 Nginx 實際的做法之後,在應用場景,我們就需要根據實際的需求來調整這些參數,來最佳化我們的程式了。
處理流程圖:
#以上這些,就是 Nginx 中一個 http 請求的生命週期了。
以上是nginx的請求如何處理?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

NGINX和Apache各有優劣,適合不同場景。 1.NGINX適合高並發和低資源消耗場景。 2.Apache適合需要復雜配置和豐富模塊的場景。通過比較它們的核心特性、性能差異和最佳實踐,可以幫助你選擇最適合需求的服務器軟件。

確認 Nginx 是否啟動的方法:1. 使用命令行:systemctl status nginx(Linux/Unix)、netstat -ano | findstr 80(Windows);2. 檢查端口 80 是否開放;3. 查看系統日誌中 Nginx 啟動消息;4. 使用第三方工具,如 Nagios、Zabbix、Icinga。

要關閉 Nginx 服務,請按以下步驟操作:確定安裝類型:Red Hat/CentOS(systemctl status nginx)或 Debian/Ubuntu(service nginx status)停止服務:Red Hat/CentOS(systemctl stop nginx)或 Debian/Ubuntu(service nginx stop)禁用自動啟動(可選):Red Hat/CentOS(systemctl disable nginx)或 Debian/Ubuntu(syst

如何在 Windows 中配置 Nginx?安裝 Nginx 並創建虛擬主機配置。修改主配置文件並包含虛擬主機配置。啟動或重新加載 Nginx。測試配置並查看網站。選擇性啟用 SSL 並配置 SSL 證書。選擇性設置防火牆允許 80 和 443 端口流量。

服務器無權訪問所請求的資源,導致 nginx 403 錯誤。解決方法包括:檢查文件權限。檢查 .htaccess 配置。檢查 nginx 配置。配置 SELinux 權限。檢查防火牆規則。排除其他原因,如瀏覽器問題、服務器故障或其他可能的錯誤。

在 Linux 中啟動 Nginx 的步驟:檢查 Nginx 是否已安裝。使用 systemctl start nginx 啟動 Nginx 服務。使用 systemctl enable nginx 啟用在系統啟動時自動啟動 Nginx。使用 systemctl status nginx 驗證啟動是否成功。在 Web 瀏覽器中訪問 http://localhost 查看默認歡迎頁面。

在 Linux 中,使用以下命令檢查 Nginx 是否已啟動:systemctl status nginx根據命令輸出進行判斷:如果顯示 "Active: active (running)",則 Nginx 已啟動。如果顯示 "Active: inactive (dead)",則 Nginx 已停止。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Atom編輯器mac版下載
最受歡迎的的開源編輯器

Dreamweaver CS6
視覺化網頁開發工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能