摘要 簡單可依賴的架構(gòu)首先需要有一個簡單可依賴的前端WebServer集群。本文通過深入調(diào)研當前主流的異步web服務(wù)器Lighttpd和Nginx,從業(yè)界使用情況、架構(gòu)原理、擴展開發(fā)、功能對比、性能對比等多個方面進行分析。 調(diào)研分析業(yè)界相關(guān)從業(yè)界使用情況來看,最新Web Server使用情況的數(shù)據(jù)如下:Nginx的使用率是6.6%,Lighttpd的使用率是0.51%。 從文檔來看,nginx中文相關(guān)文檔越來越多。來自最新的百度搜索數(shù)據(jù)顯示,nginx的網(wǎng)頁數(shù)量是lighttpd的10倍。目前國內(nèi)對于Nignx內(nèi)核深入研究的人越來越多,有淘寶、sina、騰訊等許多大公司的技術(shù)人員參與研究,并進行相關(guān)的技術(shù)交流。對于Lighttpd的研究,目前主要是公司內(nèi)部和一些學生。 從業(yè)界的點評來看,國內(nèi)外基本上結(jié)論如下:
從社區(qū)活躍度來看,Nginx每月2到3個三位版本發(fā)布。Lighttpd3位版本更新較慢,目前1.5的版本基本上沒有更新過。同時Nginx有豐富的第三方庫類。 架構(gòu)原理代碼層次 Nginx的代碼量10W行,Lighttpd是5W左右。相對來說,Nginx的代碼層次結(jié)構(gòu)更加分明,具體代碼結(jié)構(gòu)如下: Nginx和lighttpd都是采用C語言編寫的,對于基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)都有一定的處理。Nginx中關(guān)于數(shù)據(jù)結(jié)構(gòu)的代碼主要放在core文件夾里面。 Nginx主要的基礎(chǔ)代碼有:array、string、buf、file、hash、md5、內(nèi)存池、隊列、紅黑樹、time、共享鎖等。這些數(shù)據(jù)結(jié)構(gòu)對于擴展開發(fā)都非常有幫助。Lighttpd有一定的基礎(chǔ)數(shù)據(jù)封裝,但相對沒有那么明顯的設(shè)計。目前觀察到的基礎(chǔ)代碼有:bitset、buffer等。 內(nèi)存管理是所有C程序中非常值得關(guān)注的一點。Lighttpd在內(nèi)存管理上沒有做特殊的考慮,基本上都是采用系統(tǒng)內(nèi)存管理函數(shù),比如malloc/calloc等。在擴展開發(fā)中的內(nèi)存也需要擴展模塊自己考慮。Nginx在內(nèi)存管理上提供了兩種方式:1、原生malloc等的二次封裝。2、內(nèi)存池。在nginx內(nèi)部大量的使用內(nèi)存池。在擴展開發(fā)中也能直接調(diào)用內(nèi)存池進行內(nèi)存管理。此外,nginx還內(nèi)置了對tcmalloc的支持。把內(nèi)存優(yōu)化做到極致。 架構(gòu)層次 從總體架構(gòu)來看,Nginx/Lighttpd都屬于master+worker的工作模型。 但nginx相比lighttpd,在細節(jié)上處理的更加優(yōu)化,具體可以從幾個方面來談 1、 配置文件熱加載。Nginx從設(shè)計開始就支持配置文件熱加載,甚至程序的熱加載。Lighttpd本身不支持,目前業(yè)界有采用擴展方式,比如說lua,可以實現(xiàn)部分配置熱加載。 2、 強大的master進程,實現(xiàn)worker進程和master進程的各司其職。Lighttpd的master進程在fork完worker進程后,就單獨的等待worker進程的結(jié)束(或者在worker進程結(jié)束后再創(chuàng)建新的worker子進程)。Nginx的master進程負責對worker子進程的管理,并通過socket pair通信方式實現(xiàn)熱配置文件升級、優(yōu)雅重啟、熱應(yīng)用程序升級等功能。 3、 線程鎖。Lighttpd在進程之外還啟動了線程進行相關(guān)方面的工作,這會對lighttpd的性能帶來一定影響。Nginx內(nèi)部雖然提供了對線程模式的支持,但在主推的進程模式中不會出現(xiàn)額外的線程。 4、 多核機器優(yōu)化,cpu affinity。Nginx設(shè)計中考慮了對多核機器的優(yōu)化方案,能降低進程在不同cpu之間的切換次數(shù),從而提升性能。 超時處理 Lighttpd的超時處理原理非常簡單:通過alarm信號量來實現(xiàn)的。每1s出發(fā)一個alarm信號,從而切換到超時處理函數(shù)。該函數(shù)也非常簡單:循環(huán)簡單當前所有連接的讀和寫,如果事件超時了,則直接close掉。這會有幾個問題: 1、 連接非常多的時候。超時處理還是會非常耗事件的。隨著連接數(shù)而遞增。 2、 在不可重入的函數(shù)中出發(fā)alarm的時候,有可能出現(xiàn)意想不到的問題。 3、 需要輪詢。 Nginx在超時處理上實現(xiàn)的巧妙的多:采用數(shù)據(jù)結(jié)構(gòu)和巧妙的策略來實現(xiàn)。 1、 使用紅黑樹來存放定時器的相關(guān)數(shù)據(jù)。紅黑樹的重要特點是:插入刪除都會在O(logN)完成,同時具有優(yōu)秀的查找性能。所以很多C++的庫(map)等都用到了它。 2、 通過紅黑樹計算出當前節(jié)點的超時時間差,使用這個時間差作為調(diào)用多路復用I/O操作的參數(shù),當函數(shù)返回,只可能是I/O事件被觸發(fā),或者超時。 3、 處理完I/O事件之后,得到處理前后的時間差,根據(jù)這個時間差依次查看紅黑樹中哪些定時器可以被處理。 這也是在高壓力下,Nginx更優(yōu)于Lighttpd的一個重要原因。 Accept 處理 Lighttpd中對于Accept的處理有幾個特點:1、不加鎖。2、連接處理達到0.9的時候會禁止接收新的連接。3、1次性accpet 100個。這樣有一個好處, 假如服務(wù)器監(jiān)聽fd是每次觸發(fā)只接收一個新的連接, 那么效率是比較低的,不如每次被觸發(fā)的時候”盡力”的去接收, 一直到接收了100個新的連接或者沒有可接收的連接之后才返回。4、提供了fdwaitqueue。在fd不夠用的時候備用。 Nginx:1、進程加鎖,避免驚群,同時控制了獲取accpet的概率,一定程度上控制各個子進程之間的請求數(shù)目。2、7/8閥值。連接數(shù)目達到最大連接數(shù)的7/8的時候,該進程將獲取不到對應(yīng)的accept鎖。從而進入安全控制階段。3、提供了multi_accept指令,在開啟的情況下也和lighttpd一樣盡可能的多accept。 狀態(tài)機 Lighttpd和nginx都是狀態(tài)機驅(qū)動模型,兩者之間主要體現(xiàn)在細節(jié)的差異性上。
后端處理 Nginx針對不同的后端處理方式進行了封裝,提供upstream來支持不同的協(xié)議(HTTP/FASTCGI/Memcache),提供擴展來支持不同的負載均衡算法。同樣的Lighttpd在新版中也對不同的后端協(xié)議進行了封裝,并提供了不同可供選擇的負載均衡算法。 從原理層次來看,兩者在后端處理上的思路是基本一致的。更多的對比需要從功能和性能上來對比。 擴展開發(fā) Nginx和Lighttpd都支持擴展,Lighttpd是通過預留系統(tǒng)鉤子來實現(xiàn)的,相對來說不夠靈活,如果有一些特殊的修改則不得不修改源碼。Nginx則通過預留系統(tǒng)鉤子和控制反轉(zhuǎn)結(jié)合,從而能夠?qū)崿F(xiàn)更多的功能。所以,nginx擴展的靈活性高于Lighttpd。 總結(jié)如下: 1、 nginx不支持動態(tài)擴展模塊。 2、 擴展開發(fā)上,nginx更加靈活。提供了多種擴展切入方式。 3、 Nginx提供了豐富的類庫,方便擴展開發(fā)。 功能對比反向代理 對比分析如下: 1、 性能。
2、 功能。
結(jié)論: 1、功能上,nignx和lighttpd都具有完整的反向代理功能。但nginx在這方面明顯優(yōu)于lighttpd,更加完整的細節(jié)考慮和優(yōu)化。主要體現(xiàn)在超時處理、文件上傳、輸入輸出的過濾、cache等等。 2、性能上,Nginx稍優(yōu)于lighttpd。 Fastcgi 支持 Nginx和lighttpd在Fastcgi方面功能上基本上相同,主要調(diào)研是從性能上對比。 10k 的php 請求
20k 的PHP 請求
從性能數(shù)據(jù)來看,2000QPS以內(nèi),兩者性能差別不大,但高壓力下,兩者性能差別非常大。甚至有可能達到20%cpu差別。 頁面Cache 和運維 Lighttpd目前暫無頁面Cache的支持。Nginx從設(shè)計之初就考慮了更改Cache。甚至有單獨的Cache管理進程。 從功能上來看,目前Nginx已經(jīng)支持proxy cache和ssl filter,并且實現(xiàn)了對esi cache的支持。 從運維上來看,Nginx支持配置熱加載,支持程序熱加載。更適合完成24*365的全天候不間斷服務(wù)。 總結(jié)對比點匯總整理后如下
通過上述對比分析,可以得出如下結(jié)論: “l(fā)ighttpd和nginx一樣具有非常好的架構(gòu),但在數(shù)據(jù)結(jié)構(gòu)、內(nèi)存管理都多個細節(jié)方面處理nginx考慮更加完善。如果說lighttpd是異步web server的先驅(qū),那么nginx則是對lighttpd做了整體的優(yōu)化的。而這些優(yōu)化是全面的,根本性質(zhì)的。無法簡單的通過升級lighttpd來實現(xiàn)。因為nginx從一開始設(shè)計就希望做成一個完美的異步web server。nginx從event、跨平臺、基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)都很多細節(jié)方面進行了考慮和優(yōu)化。應(yīng)該來說,nginx必定是未來的apache,未來的主流?!?/p> |
|