Web服務器要爲用戶提供服務,必須以某種方式,工做在某個套接字上。通常Web服務器在處理用戶請求是,通常有以下三種方式可選擇:多進程方式、多線程方式、異步方式。html
多進程方式:爲每一個請求啓動一個進程來處理。因爲在操做系統中,生成進程、銷燬進程、進程間切換都很消耗CPU和內存,當負載高是,性能會明顯下降。
優勢: 穩定性!因爲採用獨立進程處理獨立請求,而進程之間是獨立的,單個進程問題不會影響其餘進程,所以穩定性最好。nginx
缺點: 資源佔用!當請求過大時,須要大量的進程處理請求,進程生成、切換開銷很大,並且進程間資源是獨立的,形成內存重複利用。web
多線程方式:一個進程中用多個線程處理用戶請求。因爲線程開銷明顯小於進程,並且部分資源還能夠共享,所以效率較高。
優勢:開銷較小!線程間部分數據是共享的,且線程生成與線程間的切換所需資源開銷比進程間切換小得多。apache
缺點:穩定性!線程切換過快可能形成線程抖動,且線程過多會形成服務器不穩定。緩存
異步方式:使用非阻塞方式處理請求,是三種方式中開銷最小的。但異步方式雖然效率高,但要求也高,由於多任務之間的調度若是出現問題,就可能出現總體故障,所以使用異步工做的,通常是一些功能相對簡單,但卻符合服務器任務調度、且代碼中沒有影響調度的錯誤代碼存在的程序。
優勢:性能最好!一個進程或線程處理多個請求,不須要額外開銷,性能最好,資源佔用最低。服務器
缺點:穩定性!某個進程或線程出錯,可能致使大量請求沒法處理,甚至致使整個服務宕機。多線程
客戶發起狀況到服務器網卡;
服務器網卡接受到請求後轉交給內核處理;
內核根據請求對應的套接字,將請求交給工做在用戶空間的Web服務器進程
Web服務器進程根據用戶請求,向內核進行系統調用,申請獲取相應資源(如index.html)
內核發現web服務器進程請求的是一個存放在硬盤上的資源,所以經過驅動程序鏈接磁盤
內核調度磁盤,獲取須要的資源
內核將資源存放在本身的緩衝區中,並通知Web服務器進程
Web服務器進程經過系統調用取得資源,並將其複製到進程本身的緩衝區中
Web服務器進程造成響應,經過系統調用再次發給內核以響應用戶請求
內核將響應發送至網卡
網卡發送響應給用戶
經過這樣的一個複雜過程,一次請求就完成了。併發
簡單來講就是:用戶請求-->送達到用戶空間-->系統調用-->內核空間-->內核到磁盤上讀取網頁資源->返回到用戶空間->響應給用戶。負載均衡
4.1 apache三種工做模式
咱們都知道Apache有三種工做模塊,分別爲prefork、worker、event。異步
prefork:多進程,每一個請求用一個進程響應,這個過程會用到select機制來通知。
worker:多線程,一個進程能夠生成多個線程,每一個線程響應一個請求,但通知機制仍是select不過能夠接受更多的請求。
event:基於異步I/O模型,一個進程或線程,每一個進程或線程響應多個用戶請求,它是基於事件驅動(也就是epoll機制)實現的。
4.2 prefork的工做原理
若是不用「--with-mpm」顯式指定某種MPM,prefork就是Unix平臺上缺省的MPM.它所採用的預派生子進程方式也是 Apache1.3中採用的模式。prefork自己並無使用到線程,2.0版使用它是爲了與1.3版保持兼容性;另外一方面,prefork用單獨的子進程來處理不一樣的請求,進程之間是彼此獨立的,這也使其成爲最穩定的MPM之一。
4.3 worker的工做原理
相對於prefork,worker是2.0版中全新的支持多線程和多進程混合模型的MPM。因爲使用線程來處理,因此能夠處理相對海量的請求,而系統資源的開銷要小於基於進程的服務器。可是,worker也使用了多進程,每一個進程又生成多個線程,以得到基於進程服務器的穩定性,這種MPM的工做方 式將是Apache2.0的發展趨勢。
4.4 event 基於事件機制的特性
一個進程響應多個用戶請求,利用callback機制,讓套接字複用,請求過來後進程並不處理請求,而是直接交由其餘機制來處理,經過epoll機制來通知請求是否完成;在這個過程當中,進程自己一直處於空閒狀態,能夠一直接收用戶請求。能夠實現一個進程程響應多個用戶請求。支持持海量併發鏈接數,消耗更少的資源。
有幾個基本條件:
基於線程,即一個進程生成多個線程,每一個線程響應用戶的每一個請求。
基於事件的模型,一個進程處理多個請求,而且經過epoll機制來通知用戶請求完成。
基於磁盤的AIO(異步I/O)
支持mmap內存映射,mmap傳統的web服務器,進行頁面輸入時,都是將磁盤的頁面先輸入到內核緩存中,再由內核緩存中複製一份到web服務器上,mmap機制就是讓內核緩存與磁盤進行映射,web服務器,直接複製頁面內容便可。不須要先把磁盤的上的頁面先輸入到內核緩存去。
恰好,Nginx 支持以上全部特性。因此Nginx官網上說,Nginx支持50000併發,是有依據的。
Nginx會按需同時運行多個進程:一個主進程(master)和幾個工做進程(worker),配置了緩存時還會有緩存加載器進程(cache loader)和緩存管理器進程(cache manager)等。全部進程均是僅含有一個線程,並主要經過「共享內存」的機制實現進程間通訊。主進程以root用戶身份運行,而worker、cache loader和cache manager均應以非特權用戶身份運行。
主進程主要完成以下工做:
讀取並驗正配置信息;
建立、綁定及關閉套接字;
啓動、終止及維護worker進程的個數;
無須停止服務而從新配置工做特性;
控制非中斷式程序升級,啓用新的二進制程序並在須要時回滾至老版本;
從新打開日誌文件;
編譯嵌入式perl腳本;
worker進程主要完成的任務包括:
接收、傳入並處理來自客戶端的鏈接;
提供反向代理及過濾功能;
nginx任何能完成的其它任務;
注:若是負載以CPU密集型應用爲主,如SSL或壓縮應用,則worker數應與CPU數相同;若是負載以IO密集型爲主,如響應大量內容給客戶端,則worker數應該爲CPU個數的1.5或2倍。
在高鏈接併發的狀況下,Nginx是Apache服務器不錯的替代品: Nginx在美國是作虛擬主機生意的老闆們常常選擇的軟件平臺之一. 可以支持高達 50,000 個併發鏈接數的響應, 感謝Nginx爲咱們選擇了 epoll and kqueue 做爲開發模型。Nginx做爲負載均衡服務器: Nginx 既能夠在內部直接支持 Rails 和 PHP 程序對外進行服務, 也能夠支持做爲 HTTP代理 服務器對外進行服務. Nginx採用C進行編寫, 不管是系統資源開銷仍是CPU使用效率都比 Perlbal 要好不少。做爲郵件代理服務器: Nginx 同時也是一個很是優秀的郵件代理服務器(最先開發這個產品的目的之一也是做爲郵件代理服務器), Last.fm 描述了成功而且美妙的使用經驗.Nginx 安裝很是的簡單 , 配置文件很是簡潔(還可以支持perl語法),Bugs 很是少的服務器: Nginx 啓動特別容易, 而且幾乎能夠作到7*24不間斷運行,即便運行數個月也不須要從新啓動. 你還可以 不間斷服務的狀況下進行軟件版本的升級 。Nginx 的誕生主要解決C10K問題