調用HTTP模塊的流程:nginx
Worker進程會在一個for循環語句中反覆調用事件模塊檢測網絡事件。當事件模塊檢測到某個客戶端發起的TCP請求時(接收到SYN包),將會爲它創建TCP鏈接,成功創建鏈接後根據nginx.conf文件中的配置會交由HTTP框架處理。HTTP框架會試圖接收完整的HTTP頭部,並在接受到完整的HTTP頭部後將請求分發到具體的HTTP模塊中處理。這種分發策略是多樣化的,最多見的是根據請求的URI和nginx.conf裏location配置項的匹配度來決定如何分發。HTTP模塊在處理請求的結束時,大多會向客戶端發送響應,此時會自動地依次調用全部的HTTP過濾模塊,每一個過濾模塊能夠根據配置文件決定本身的行爲。web
事件類型的模塊主要處理I/O事件相關的功能,HTTP類型的模塊主要處理HTTP應用層的功能。數組
Nginx在解析配置文件中的一個配置項時首先會遍歷全部的模塊,對於每個模塊而言,即經過遍歷commands數組進行,另外,在數組中檢查到ngx_null_command時,會中止使用當前模塊解析該配置項。=>個人理解:若是在某模塊中找到該配置項名稱,則調用該模塊中commands數組的set方法來解析該配置項。Set方法中會調用ngx_http_mytest_handler函數服務器
1、Nginx的架構設計網絡
1)優秀的模塊化設計數據結構
1)高度抽象的模塊接口架構
全部的模塊都遵循着一樣的ngx_module_t接口設計規範,ngx_module_t是全部模塊的通用接口併發
2)模塊接口很是簡單,具備很高的靈活性負載均衡
模塊的基本接口ngx_module_t足夠簡單,只涉及模塊的初始化、退出以及對配置項的處理框架
3)配置模塊的設計
配置模塊的類型是NGX_CONF_MODULE,它僅有的模塊爲ngx_conf_module,這是Nginx最底層的模塊,它指導着全部模塊以配置項爲核心來提供功能
4)核心模塊接口的簡單化
基礎類型的模塊:核心模塊,它的模塊類型爲NGX_CORE_MODULE,目前官方的核心類型模塊中共有6個具體模塊,分別是ngx_core_module,ngx_errlog_module,ngx_events_module,ngx_openssl_module,ngx_http_module,ngx_mail_module模塊。定義核心模塊是爲了讓非模塊化的框架代碼只關注於如何調用6個核心模塊
核心模塊的接口以下,它將ctx上下文進一步實例化爲ngx_core_module_t結構體:
typedef struct{
//核心模塊名稱
ngx_str_t name;
void *(*create_conf)(ngx_cycle_t *cycle);
char *(*init_conf)(ngx_cycle_t *cycle,void *conf);
}ngx_core_module_t;
ngx_core_module_t上下文是以配置項的解析做爲基礎的,它提供了create_conf回調方法來建立存儲配置項的數據結構,在讀取nginx.conf配置文件時,會根據模塊中的ngx_command_t把解析出的配置項存放在這個數據結構中;它還提供了init_conf回調方法,用於在解析完配置文件後,使用解析出的配置項初始化核心模塊功能。
上述設計使得每一個核心模塊均可以自由地定義全新的模塊類型,新定義的模塊由核心模塊管理。
5)多層次、多類別的模塊設計
官方Nginx共有五大類型的模塊:核心模塊、配置模塊、事件模塊、HTTP模塊、mail模塊。
配置模塊和核心模塊由Nginx的框架代碼定義,其餘3種模塊都不會和框架產生直接關係。
事件模塊、HTTP模塊、mail模塊這三種模塊在覈心模塊中各有一個模塊做爲本身的代言人,並在同類模塊中有一個做爲核心業務與管理功能的模塊
在這5中模塊中,配置模塊與核心模塊都是與Nginx框架密切相關的,是其餘模塊的基礎。而事件模塊則是HTTP模塊和mail模塊的基礎。在事件模塊中,ngx_event_core_module事件模塊是其餘全部事件模塊的基礎;在http模塊中,ngx_http_core_module模塊是其餘全部HTTP模塊的基礎;在mail模塊中,ngx_mail_core_module模塊是其餘全部mail模塊的基礎。
2)事件驅動架構
事件驅動架構是指由一些事件發生源來產生事件,由一個或多個事件收集器來收集、分發事件,而後許多事件處理器會註冊本身感興趣的事件,同時會消費這些事件。
對於Nginx而言,通常會由網卡、磁盤產生事件,事件模塊將負責事件的收集、分發操做,而全部的模塊均可能是事件消費者。
Nginx採用徹底的事件驅動架構來處理業務。對於傳統web服務器而言,事件驅動每每侷限在TCP連接創建、關閉事件上,一個鏈接創建之後,在其關閉以前的全部操做逗再也不是事件驅動,這時會退化成按序執行每一個操做的批處理模式,這樣每一個請求在連接創建後都將始終佔用着系統資源,知道鏈接關閉纔會釋放資源。傳統web服務器每每把進程或線程做爲事件消費者,當一個請求產生的事件被該進程處理時,知道這個請求處理結束時進程資源都將被這個請求所佔用。
Nginx只有事件收集、分發器纔有資格佔用進程資源,它們會在分發某個事件時調用事件消費模塊使用當前佔用的進程資源。
3)請求的多階段異步處理
即把一個請求的處理過程按照事件的觸發方式分爲多個階段,每一個階段均可以由事件收集、分發器來觸發。
關鍵在於劃分請求的階段,通常是找到請求處理流程中的阻塞方法(或者形成阻塞的代碼段),在阻塞代碼段上按照下面4種方式來劃分階段:
1.將阻塞進程的方法按照相關的觸發事件分解爲兩個階段
大部分狀況下,一個阻塞進程的方法調用時能夠劃分爲兩個階段:阻塞方法改成非阻塞方法調用,這個調用非阻塞方法並將進程歸還給事件分發器的階段就是第一階段;增長新的處理階段用於處理非阻塞方法最終返回的結果,這裏的結果返回事件就是第二階段的觸發事件
2.將阻塞方法調用按照時間分解爲多個階段的方法調用
系統中的事件收集、分發者並不是能夠處理任何事件,若是按照前一種方式試圖劃分某個方法時,那麼可能會發現找出的觸發事件不可以被事件收集、分發器所處理,這時只能按照執行時間來拆分這個方法。
例如讀取10MB的文件(ngx_epoll_module模塊主要是針對網絡事件),能夠這樣來分解讀取文件調用:每次只讀取10kb,這樣該事件接收器佔用進程的時間不會過久,整個進程能夠及時地處理其餘請求。
在讀取0-10kb後,爲了進入10kb-20kb階段,能夠用能被事件收集器處理的事件來觸發,或者設置一個定時器。
3.在無所事事且必須等待系統的響應,從而致使進程空轉時,使用定時器劃分階段
當定時器事件發生時就會檢查標誌,若是標誌位不知足,就馬上歸還進程控制權,同時繼續加入指望的下一個定時器事件
4.若是阻塞方法徹底沒法繼續劃分,則必須使用獨立的進程執行這個阻塞方法
4)管理進程、多工做進程設計
Nginx採用一個master管理進程、多個worker工做進程的設計方式。
優勢:
1.利用多核系統的併發處理能力。
Nginx中全部的worker工做進程都是徹底平等的。
2.負載均衡
多個worker工做進程間經過進程間通訊來實現負載均衡,當一個請求到來時更容易被分配到負載較輕的worker工做進程中處理。
3.管理進程會負責監控工做進程的狀態,並負責管理其行爲。
5)內存池的設計
優勢:把屢次向系統申請內存的操做整合成一次,大大減小了cpu資源的消耗,同時減小了內存碎片,提升了內存的有效利用率和系統可處理的併發鏈接數。
2、Nginx框架中的核心結構體ngx_cycle_t
ngx_listening_t結構體
ngx_cycle_t對象中有一個動態數組成員叫作listening,它的每一個數組元素都是ngx_listening_t結構體,而每一個ngx_listening_t結構體表明着Nginx服務器監聽的一個端口。
ngx_cycle_t結構體
Nginx框架是圍繞着ngx_cycle_t結構體來控制進程運行的。ngx_cycle_t結構體的prefix,conf_prefix,conf_file等字符串類型成員保存着Nginx配置文件的路徑。
3、Nginx啓動時框架的處理流程
4、worker進程工做流程
5、master進程工做流程
參考:
http://blog.csdn.net/xifeijian/article/details/17385831