Nginx服務器架構簡析

一.Nginx的模塊化web

模塊化結構的思想是一個好久的概念,但也正是成熟的思想造就了Nginx的巨大優越性。segmentfault

咱們知道Nginx從整體上來說是有許多個模塊構成的。習慣將Nginx分爲5大模塊分別爲:核心模塊,標準HTTP模塊,可選HTTP模塊,郵件服務模塊和第三方模塊。後端

這5個模塊由上到下重要性一次遞減。緩存

(1)核心模塊;服務器

核心模塊是Nginx服務器正常運行必不可少的模塊,如同操做系統的內核。它提供了Nginx最基本的核心服務。像進程管理、權限控制、錯誤日誌記錄等;網絡

(2)標準HTTP模塊;多線程

標準HTTP模塊支持標準的HTTP的功能;架構

(3)可選HTTP模塊;併發

可選HTTP模塊主要用於擴展標準的HTTP功能,讓Nginx能處理一些特殊的服務;異步

(4)郵件服務模塊;

郵件服務模塊主要用於支持Nginx的郵件服務;

(5)第三方模塊;

第三方模塊是爲了擴展Nginx服務器應用,完成開發者想要的功能;

*******Nginx中的模塊命名有本身的習慣*********

通常以Ngx_做爲前綴,——module做爲後綴,中間使用一個或者多個英文單詞描述模塊的工能,例如Ngx_core_module表示該模塊提供Nginx的核心功能等;

具體各個模塊中包含哪些模塊能夠本身去源碼中查詢,這裏略過;

 

二.Nginx的web請求處理機制

從架構設計上說,Nginx服務器是不同凡響的。其一在於它的模塊化設計其二也是更重要的一點在於它對與客戶端請求的處理機制上

web服務器和客戶端是一對多的關係,Web服務器必須有能力同時爲多個客戶端提供服務。通常來講完成並行處理請求工做有三種方式:

1.多進程方式;

2.多線程方式;

3.異步方式;

這裏簡單說明一下這三種方式:

(1)多進程方式

多進程方式指,服務器每當收到一個客戶端時。就有服務器主進程生成一個子進程出來和客戶端創建鏈接進行交互。指導鏈接斷開。該子進程就結束了。

多進程方式的優勢是設計簡單,各個子進程相對獨立,處理客戶端請求時彼此不受干擾;缺點是操做系統生成一個子進程須要進行內存複製等操做,在資源和時間上會產生必定的開銷;當有大量請求時,會致使系統性能降低;

(2)多線程方式

多線程方式指每當服務器接收到一個請求後,會由服務器主進程派生出一個線程出來和客戶端進行交互。因爲操做系統產生出一個線程的開銷遠遠小於一個進程的開銷。故多線程方式在很大程度上減輕了Web服務器對系統資源的要求。但同時因爲多個線程位於一個進程內,能夠訪問一樣的內存空間。因此須要開發者本身對內存進程管理,增大了難度。

(3)異步方式

異步方式適合多進程和多線程徹底不一樣的一種處理客戶端請求的方式。這裏有幾個概念咱們須要熟悉一下:同步,異步,阻塞,非阻塞

在網絡通訊中同步和異步是描述通訊模式的概念。

同步發送方發送完請求後,須要等待接收到接收方發回的響應,才能發送下一個請求;全部請求在服務端獲得同步,發送方和接收方的步調是一致的;

異步和同步機制相反,在異步機制中,發送方發出一個請求後,不等接收方響應這個請求,就繼續發送下一個請求;全部來自發送方的請求造成一個隊列,接收方處理完成後通知發送方;

在進程處理調度方式上用阻塞與非阻塞。在網絡通訊中主要指套接字socket的阻塞和非阻塞,而socket的實質就是IO操做。

阻塞調用結果返回以前,當前線程從運行狀態被掛起,一直等到調用結果返回以後,才進入就緒狀態,獲取CPU後繼續執行。

非阻塞和阻塞方式正好相反,若是調用結果不能立刻返回,當前線程也不會立刻返回,而是當即返回執行下一個調用。

所以就衍生出4中方式:同步阻塞,同步非阻塞,異步阻塞,異步非阻塞

這裏簡單解釋一下異步非阻塞:發送方向接收方發送請求後,不用等待響應,能夠繼續其餘工做;接收方處理請求時進行的IO操做若是不能立刻獲得結果,也沒必要等待,而是立刻返回去去作其餘事情。當IO操做完成之後,將完成狀態和結果通知接收方,接收方再響應發送方。

與此同時Nginx服務器處理請求是怎樣的呢???

Nginx服務器的一個顯著的優點就是可以同時處理大量的併發請求。它結合多進程機制和異步機制。異步機制使用的是異步非阻塞方式。(Master-Worker)。

每一個工做進程使用異步非阻塞方式,能夠處理多個客戶端請求。當某個工做進程接收到客戶端的請求之後,調用IO進行處理,若是不能當即獲得結果,就去處理其餘的請求;而客戶端在此期間也無需等待響應,能夠去處理其餘事情;當IO返回時,就會通知此工做進程;該進程獲得通知,暫時掛起當前處理的失誤去響應客戶端請求。

也就是:

Nginx採用異步非阻塞方式來處理請求,處理請求具體到系統底層就是讀寫事件(所謂阻塞調用方式即請求事件還沒準備好,線程只能一直去等,等事件準備好了再處理;而非阻塞即事件沒準備好,立刻返回ENGAIN,告訴你事件還沒準準備好,而在這期間能夠先去作其餘事,再回頭看看事件準備好了嗎,時不時會看,須要的開銷也是不小的)
異步能夠理解爲循環處理多個準備好的事件,不會致使無謂的資源浪費,當有更多的併發數只會佔用更多的內存而已;
 
三.Nginx服務器的實踐驅動模型
從上面咱們能夠知道,Nginx服務器的工做進程調用IO後,就取進行其餘工做了;當IO調用返回後,會通知工做進程。但IO調用時如何把本身的狀態通知給工做進程的呢??
通常解決這個問題有兩種方法:(1)讓工做進程在進行其餘工做的過程當中間隔一段時間就去檢查一下IO的狀態,若是完成就響應客戶端,若是未完成,繼續工做。
                                        (2)IO調用在完成後能主動通知工做進程。
固然最好的就是用第二種方法了;像select/poll/epoll等這樣的系統調用就是用來支持第二種解決方案的。這些系統調用也常被稱爲事件驅動模型。他們提供了一種機制就只讓進程同時處理多個併發請求,不用關心IO調用的具體狀態。IO調用徹底由事件驅動模型來管理。
 
Nginx中的事件驅動模型
就是用事件驅動處理庫(多路IO複用),最經常使用的就是select模型,poll模型,epoll模型。
關於這三個模型的詳解在這裏能夠看到:http://www.javashuo.com/article/p-sqagmtjn-x.html
 
四.架構簡介
經過這個上面的簡單講解,再加上服務器的架構的瞭解,能夠對Nginx有一個簡單的瞭解,但願對以後的源碼剖析有幫助。
大體上Nginx的架構就是這樣:
1.Nginx啓動後,會產生一個主進程,主進程執行一系列的工做後會產生一個或者多個工做進程;
2.在客戶端請求動態站點的過程當中,Nginx服務器還涉及和後端服務器的通訊。Nginx將接收到的Web請求經過代理轉發到後端服務器,由後端服務器進行數據處理和組織;
3.Nginx爲了提升對請求的響應效率,下降網絡壓力,採用了緩存機制,將歷史應答數據緩存到本地。保障對緩存文件的快速訪問;
 
##工做進程##
工做進程的主要工做有如下幾項:
接收客戶端請求;
將請求一次送入各個功能模塊進行過濾處理;
IO調用,獲取響應數據;
與後端服務器通訊,接收後端服務器處理結果;
數據緩存
響應客戶端請求;
 
##進程交互##
Nginx服務器在使用Master-Worker模型時,會涉及到主進程和工做進程的交互和工做進程之間的交互。這兩類交互都依賴於管道機制。
1.Master-Worker交互
這條管道與普通的管道不一樣,它是由主進程指向工做進程的單向管道,包含主進程向工做進程發出的指令,工做進程ID等;同時主進程與外界經過信號通訊;
2.worker-worker交互
這種交互是和Master-Worker交互是基本一致的。可是會經過主進程。工做進程之間是相互隔離的,因此當工做進程W1須要向工做進程W2發指令時,首先找到W2的進程ID,而後將正確的指令寫入指向W2的通道。W2收到信號採起相應的措施。 
 
 
參考:《Nginx高性能Web服務器詳解》
相關文章
相關標籤/搜索