nginx處理http請求流程
監聽套接字ngx_listenting_t->fd由獲取accept_mutex的worker程式加入epoll監控,其handler為ngx_event_accept;
注:每個fd賦予一個ngx_connection_t,且c->read->handler = ngx_event_accept(詳見ngx_event_process_init);
當客戶端發起新連線時,epoll_wait返回,將其加入accepted佇列,然後呼叫ngx_event_accept處理;
接受完客戶端連線後,立即呼叫ngx_listening_t->handler,即ngx_http_init_connection;
ngx_http_init_connection
將當前連線的讀事件revent->handler設定為ngx_http_init_request;
將當前連線的讀事件revent加入定時器,超時時間為client_header_timeout;
將當前連線的讀事件revent加入epoll監控;
注:當連線第一次出現可讀事件時,才會呼叫ngx_http_init_request
ngx_http_init_request
檢查是否超時client_header_timeout;
建立ngx_http_request_t,
將revent->handler重置為ngx_http_process_request_line;
建立讀緩衝區client_header_buffer_size && ngx_http_request_t記憶體池
為ngx_http_request_t->ctx分配ngx_http_max_module個成員的指標陣列(注1);
呼叫ngx_http_process_request_line;
ngx_http_process_request_line
接收請求行,格式為: 請求方法 uri http版本;
可呼叫多次;
執行完畢後將revent->handler重置為ngx_http_process_request_headers;
ngx_http_process_request_headers
解析請求頭;
呼叫ngx_http_process_request處理http請求;
ngx_http_process_request
把讀事件從定時器移除,無需再接受http請求頭;
將當前連線讀事件c->read->handler設定為ngx_http_request_handler;
檢查ngx_http_request_t->internal,為1表示需要跳轉,將phase_handler改為server_rewrite_index,即呼叫NGX_HTTP_SERVER_REWRITE_PHASE階段的handler;
設定ngx_http_request_t->write_event_handler = ngx_http_core_run_phases;
呼叫ngx_http_core_run_phases;
執行post子請求;
問1:nginx擁有眾多http模組,如何將其整合並確保http請求會用到相應模組?
nginx將http請求劃分11個階段,每一階段可包含多個http模組,每個模組handler執行結果決定下一個模組;
每個http階段由ngx_http_phase_handler_s描述,包含3個成員:checker,handler以及 next;
Nginx不允許直接呼叫http模組的handler,而是透過提供的checker封裝呼叫,共有7個http請求階段實現了checker(4個),也就是說只有這7個階段允許第3方模組註冊;
Nginx初始化時,呼叫每個http模組的ngx_http_module_t->postconfiguration將自身的handler加入cmcf->phases(二維陣列);
然後透過ngx_http_init_phase_handlers()將cmcf->phases重組為一維陣列cmcf->phase_engine.handlers,此時所有的ngx_http_phase_handler_s都位於其中;
一個http請求經過解析請求行和請求頭後,最終呼叫ngx_http_core_run_phases,其以http請求的phase_handler為下標,嘗試遍歷cmcf->phase_engine.handlers (可能因為處理結果提前返回)
ngx_http_core_run_phases(ngx_http_request_t *r)
{
ngx_int_t rc;
ngx_http_phase_handler_t *ph;
ngx_http_core_main_conf_t *cmcf;
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
ph = cmcf->phase_engine.handlers;
while (ph[r->phase_handler].checker) {
rc = ph[r->phase_handler].checker(r, &ph[r->phase_handler]);
if (rc == NGX_OK) {
return;
}
}
}
以上是接受客戶端連線,並根據http請求行和請求頭執行相應http模組,http請求可能還有包體,由http模組負責處理;
一般有兩種方法: 1 接收包體並存入記憶體或檔案; 2 接收包體後直接丟棄;
注1: http請求上下文
Nginx採用全非同步機制,一個http請求可能要多次排程http模組才能完成,需要上下文結構體儲存處理過程的中間狀態;
一個http請求對應每個http模組都有一個獨立的上下文結構體,由ngx_http_request_t -> ** ctx儲存;
每個模組上下文結構體各異,通常在http請求第一次呼叫handler時分配;
Nginx提供兩個宏用於獲取和設定上下文
#define ngx_http_get_module_ctx(r,module) (r)->ctx[module.ctx_index]
#define ngx_http_set_ctx(r, c, module) r->ctx[module.ctx_index] = c;
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29734436/viewspace-1406853/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Nginx請求處理流程你瞭解嗎?Nginx
- .NET處理HTTP請求HTTP
- Mongodb請求處理流程MongoDB
- SpringMVC請求處理流程SpringMVC
- nginx 如何處理一個請求Nginx
- 圖解 Spring:HTTP 請求的處理流程與機制【1】圖解SpringHTTP
- .NET處理HTTP請求——摘自網路HTTP
- go http請求流程分析GoHTTP
- 4、Ktor學習-處理HTTP請求;HTTP
- Laravel 底層是如何處理HTTP請求LaravelHTTP
- 通過重建Hosting系統理解HTTP請求在ASP.NET Core管道中的處理流程[中]:管道如何處理請求...HTTPASP.NET
- 在 .NET 中使用 Flurl 高效處理Http請求HTTP
- ASP.Net請求處理機制初步探索之旅(5):ASP.Net MVC請求處理流程ASP.NETMVC
- java 請求HTTP返回json集合,物件處理方式JavaHTTPJSON物件
- 理解 Nginx 在處理請求時的匹配規則Nginx
- nginx 處理客戶端請求的完整過程Nginx客戶端
- AngularJS中的$http快取以及處理多個$http請求AngularJSHTTP快取
- Spring MVC 處理一個請求的流程分析SpringMVC
- Spring MVC框架處理Web請求的基本流程SpringMVC框架Web
- Tomcat 第四篇:請求處理流程(上)Tomcat
- SpringMVC底層——請求引數處理流程描述SpringMVC
- Java Struts2 的請求處理流程詳解Java
- Tomcat總體架構,啟動流程與處理請求流程Tomcat架構
- nginx遮蔽特定http_referer的請求NginxHTTP
- 萬字長文!一次性弄懂 Nginx 處理 HTTP 請求的 11 個階段NginxHTTP
- 【第二章】深入HTTP請求流程HTTP
- Angular 記錄 - Rxjs 完整處理一個 Http 請求AngularJSHTTP
- Angular Universal Application 應該處理 HTTP POST 請求嗎?AngularAPPHTTP
- Scrapy原始碼閱讀分析_4_請求處理流程原始碼
- 請求資料處理
- wordpress 處理 ajax 請求
- 處理REST SOE請求REST
- 死磕Spring原始碼-MVC處理HTTP分發請求Spring原始碼MVCHTTP
- 多執行緒應用–Http請求阻塞回撥處理執行緒HTTP
- 多執行緒應用--Http請求阻塞回撥處理執行緒HTTP
- 一個請求在Struts2框架中的處理流程框架
- http請求HTTP
- HTTP 請求HTTP