nginx並發模型與traffic_server並發模型簡單比較
ginx並發模型:
nginx
的進程模型采用的是prefork方式,預先分配的worker子進程數量由配置文件指定,默認為1,不超過1024。master主進程創建監聽套接口,fork子進程以後,由worker進程監聽客戶連接,每個worker子進程獨自嘗試accept已連接套接口,accept是否上鎖可以配置,默認會上鎖,如果操作系統支持原子整型,才會使用共享內存實現原子上鎖,否則使用文件上鎖。不使用鎖的時候,當多個進程同時accept,當一個連接來的時候多個進程同時被喚起,會導致驚群問題。使用鎖的時候,只會有一個worker阻塞在accept上,其他的進程則會不能獲取鎖而阻塞,這樣就解決了驚群的問題。master進程通過socketpair向worker子進程發送命令,終端也可以向master發送各種命令,子進程通過發送信號給master進程的方式與其通信,worker之間通過unix套接口通信。
模型如下圖:
Traffic server並發模型:多線程異步事件處理
traffic_cop和traffic_manager作為管理進程,工作進程為traffic_server,traffic_server負責listen和accept,為提高性能,traffic_server使用了異步I/O和多線程技術。Traffic
Server並不是為每個連接都建立一個線程,而是事先創建一組數量可配置的工作線程,每一個工作線程上都運行著獨立的異步事件處理程序。traffic_server創建若幹組Thread,並將Event按類型調度到相應的Thread的Event隊列上,Thread通過執行Event對應的Continuation中的回調函數,來完成狀態的遷移。從初始態到終止態的遷移代表了整個事件的執行過程,而Thread是永不退出的,等待著下一個事件的到來。模型如下圖:
兩種服務器都涉及到網絡I/O操作,nginx使用的是linux的epoll模型,traffic server使用異步I/O,由於對於I/O不熟悉,這份就不做深入對比。都使用預分配機制,nginx預分配worker進程,traffic server 預分配工作線程。
對比分析:
1.並發度:
nginx使用的多進程並發模型,采用多進程監聽新連接,為此它不需要分發操作,但是引入鎖來保持同步,舍去了分發的開銷,但是引入了鎖的開銷。實際中鎖的開銷比較小,如果系統支持原子整形,那麽鎖的開銷會進一步降低;通過worker進程自己主動去accept,這也會讓各個worker進程的負載量比較均衡,這依賴於系統內核對進程的公平的調度。worker進程也可以配置成使用線程進行事件處理工作,但模型上還是屬於多進程並發,因為線程需要從進程這裏取到事件。這種設計有一個缺陷,worker進程的數量不能太多,nginx設計的worker進程數量的最大值為1024,太多的worker進程會導致進程之間競爭資源頻繁,使系統運行緩慢。可見nginx被設計成輕量級的web服務器,但是作為輕量級的web服務器,它有著非常好的性能表現,有報告表明能支持高達 50,000個並發連接數。nginx不愧是輕量級web反向代理服務器的首選。
而traffic server使用多線程異步事件處理模型:將多線程技術與異步事件處理技術結合在一起來提高並發和性能。多線程程序可以充分利用現代處理器多核的處理能力,使一個進程的多個任務可以並行執行,提高程序執行的效率。這種多線程的設計也讓traffic server的性能與處理器的性能一直成正比,不會像nginx收到worker進程數目的約束。它不是作為輕量級的web服務器而設計的,它支持集群,Apache Traffic Server v.3.0.0基準測試的結果是每秒鐘可以處理200,000多個請求,可見traffic server不愧是高性能的web服務器,個人認為這款服務器將會是以後的發展趨勢。
2.響應時間
nginx采用的是worker進程獨立accept而直接進行處理的方式處理客戶請求,因此nginx的響應速度應該是很快的,個人覺得應該比traffic server服務器要更快。
traffic server是server進程接受請求,然後分發到請求隊列中,再由處理線程進行處理,所以理論上響應時間沒有nginx快。
網絡上的測試文檔有表明在請求靜態網頁的時候,響應速度時間約為5:7,(網上數據,本人沒有測試),和分析相符。
3.穩定性
nginx由於是很多能夠獨立工作的worker進程在工作,當其中的某個或一些worker進程異常時不影響系統的正常工作。master進程在初始化worker進程以後就在循環體中檢測信號,然後處理信號,由於master進程一直會比較穩定,當它發現worker進程異常時,又會去重啟該worker進程,而且還會檢查其他worker進程。可見nginx的這種設計容錯性是很高的。
traffic server中由於server是工作進程,而且只有一個,因此系統要保障它的正常運行。為此系統添加了traffic_cop進程與traffic_manager進程來管理server進程,給server進程加上了雙重的保障,當server異常時,traffic_manager進程會及時的重啟它,而且在重啟的過程中還會繼續利用traffic_manager進程來接受客戶請求,這是個不錯的設計。當traffic_manager進程和sever進程同時異常結束的時候,traffic_cop又會重啟它們,因此系統的穩定性也是很高的。
由於traffic server重啟的過程中無法繼續服務,因此穩定性上nginx要勝過traffic server。
4.峰值響應
web服務器都很關心當一小段時間內有大量的連接請求的時候服務器的響情況的。
nginx由於是多個worker進程工作,大量請求來的時候各個worker的負載會比較均勻分布,當峰值過高時,會導致worker進程調度延遲,也就會阻塞客戶請求,說明服務器的處理能力會阻塞客戶請求,它們之間會存在一個約束關系。另外而Nginx采取了分階段資源分配技術,由cache manager進程和cache loader 進程處理,這種設計也會使得nginx在遇到峰值請求的時候不輕易的將內存耗盡,不容易造成系統在過載請求下異常結束。
traffic server使用server進程接收到大量的用戶請求後會發送到請求隊列,然後線程在處理的時候會造成數據量過大,容易內存耗盡,出現異常導致server進程也退出,雖然會很快的重啟該進程(官方文檔說重啟只需要幾秒鐘),而且重啟的過程中還會由manager進程繼續接受請求,但是系統卻在這段時間內無法處理請求,但是nginx不會停止處理請求。(traffic server沒有集群的情況下)
分析說明在短時間爆發性訪問的時候nginx的響應能力要優於traffic server。這裏說的過載請求量是針對它們各自不同的請求量,比如nginx處理能力為50000連接,那麽它的峰值就是50000,它們的反應僅是針對各自的峰值請求。但是traffic server支持集群,這將會很大程度的的提高其峰值響應能力。
5.安全性
nginx對於安全性做的工作不多,惡意連接攻擊可能會導致worker進程耗盡系統資源而停止響應,雖然master進程會檢測並嘗試重啟,如果master進程也是去響應,那麽系統就需要重啟。但是nginx采用分階段資源分配技術,系統很難會耗盡全部的資源而是去響應,因此一般的dos攻擊對於nginx是沒什麽效果的。總體來說安全性一般。
traffic server在安全性方面做了很多工作,系統會周期性調用heartbeat_manager函數和heartbeat_server函數來檢查manager進程和server進程的健康狀況,發現不正常時則會立即重啟響應的異常進程。而且一旦server進程異常結束,也會很快被重啟。因此當收到攻擊的時候,traffic server會比較及時的作出反應,系統安全性比較高。
總結:個人認為nginx是多進程並發模型的典範,而traffic server是多線程異步事件處理模型的典範,各有其優缺點。nginx是一款優秀的輕量級web服務器,適合處理請求不多的情況;traffic server則是一款高性能web服務器,還支持集群,更適合處理大量請求連接的情況。
nginx並發模型與traffic_server並發模型簡單比較