Nginx請求處理流程

多種流量進入nginx后,nginx的三種狀態機[非阻塞驅動模型epoll]: 傳輸層狀態機,http狀態機,mail狀態機
在nginx解析出請求后,會動用線程池處理調用,將靜態資源,反向代理,錯誤日志等信息分別導向不同的出口,如: fastcgi會導向php處理,html會導向nginx處理.並將處理的請求記錄日志到本地或遠程服務器
Nginx接受請求連接事件模塊流程
操作系統內核:
三次握手,當用戶發來一個 SYN 報文時,系統內核會返回一個SYN+ACK確認給客戶端,當用戶再次發送ACK來的時候,此時就已經建立了三次握手.
完成三次握手后,操作系統會根據系統內的負載均衡算法來選中一個worker線程,它會返回一個建立連接的epoll_wait的句柄.
拿到了epoll_wait的連接句柄后找到它監聽的端口 80 或 443 等端口.
拿到端口后,開始調用accept方法來分配512字節的連接內存池 (connection_pool_size:512).
分配完內存池后,http模塊會從事件中接入請求的處理過程.
http模塊啟動后,ngx_http_init_connection設置並啟用一個回調方法: epoll_ctl, 並為這個方法添加定時器 (client_header_timeout:60s)
然后將讀事件添加到這個epoll事件中.並開始計時60s. 如果60秒沒收到請求就會返回超時.
在請求完成后,nginx會將請求數據讀取到用戶態中,並在連接內存池中為他分配一個讀的緩沖區: clent_header_bufer_size:1k
[之前分配的是512字節,這里是可擴展的分配的1k,這里的1k 是強制占用,無論你現有字節會不會超過1k 都會強行占用1k]
接收請求HTTP模塊:
收到請求的URI后,開始分配內存池,並做上下文分析,分析每個head和http協議,所以這里需要分配一個默認請求內存池: request_poll_size:4k;
此時狀態機會解析請求行,如:方法名,url,協議, 解析請求行的過程中 可能會發現有的URL更大,已經超過了我們之前設置的1k了
此時我們會調用一個大內存: large_client_header_buffers: 4 8k; (最多32k).
當狀態機解析完了請求行后,標識URI用於指向請求行(這里也是nginx強大的原因,他可以指定請求行,不用遍歷). 標識結束后,開始接受head,並開始解析header
同時復用large_client_header_buffers: 4 8k;的的內存.接收完整的header后,標識header,並且移除超時定時器 (clent_header_timeout:60s),移除定時器后就開始了 11 個階段的http請求處理過程.
