Web server调研分析
簡單可依賴的架構(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é)論如下:
- 兩者都是異步WebServer,都采用了狀態(tài)機。本質(zhì)上是相同的。
- Nginx穩(wěn)定度高于Lighttpd。Lighttpd一直存在一定的內(nèi)存泄漏。
- 性能上兩者都非常優(yōu)秀,Nginx有一定優(yōu)勢。
- Nginx在綜合性能上更加優(yōu)秀,更有可能成為未來的apache。
從社區(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、? 性能。
- 同等壓力下,nginx的cpu消耗要低于lighttpd。但整體差別不大。
- 極限壓力下,nginx處理能力高于lighttpd。原因未知。
2、? 功能。
| 功能點 | Lighttpd | Nginx | 備注 |
| 靈活的反向代理方式 | 支持 | 支持 | 都非常好 |
| 正則 | 支持 | 支持 | ? |
| 自定義header頭 | 部分支持 | 支持 | 目前gm有庫支持IP的傳遞 |
| 負載均衡 | 支持 | 支持 | ? |
| 超時處理 | 支持 | 支持連接、讀寫等 | ? |
| 故障處理 | 支持 | 支持 | ? |
| Cache | 不支持 | 支持 | ? |
| 文件上傳 | 未知 | 支持,可配置,有優(yōu)化 | Transmit不支持 |
| 輸出過濾 | 不支持 | 支持 | 頭部過濾和內(nèi)容過濾。 |
結(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請求
| 前端壓力 | Lighttpd | Nginx | 備注 |
| 1000QPS | 96% 處理1000QPS | 98% | ? |
| 2000QPS | 91% | 96% | ? |
| 4000QPS | 81% | 92% | ? |
| 8000QPS | 65% | 85% | ? |
20k的PHP請求
| 前端壓力 | Lighttpd | Nginx | 備注 |
| 1000QPS | 95% 處理1000QPS | 98% | ? |
| 2000QPS | 90% | 95% | ? |
| 4000QPS | 80% | 90% | ? |
| 8000QPS | 63%實際處理5588 QPS | 86%。實際處理5220QPS | ? |
從性能數(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é)
對比點匯總整理后如下
| 對比點 | Nginx | Lighttpd | 備注 |
| 市場占有率 | 6.6% | 0.5% | ? |
| 文檔 | ? | ? | 百度文檔10:1Google文檔 1:1 ? 國內(nèi)研究人員nginx>lighttpd |
| 業(yè)界點評 | ? | ? | 更加看好Nginx |
| 代碼量 | 10W | 5W | Nginx的代碼結(jié)構(gòu)層次較好。 |
| 基礎(chǔ)數(shù)據(jù)結(jié)構(gòu) | array、string、buf、file、hash、md5、內(nèi)存池、隊列、紅黑樹、time、共享鎖 | bitset、buffer | 豐富的庫類對擴展開發(fā)有很大幫助 |
| 內(nèi)存管理 | 原生malloc、內(nèi)存池、支持tcmalloc | 原生malloc | ? |
| 配置文件熱加載 | 支持 | 不支持 | ? |
| 進程模型 | Master負責管理,worker負責處理請求,各司其職。 | Master簡單。Worker復雜 | ? |
| 進程額外線程 | 無 | 有 | 存在線程鎖 |
| 多核機器優(yōu)化 | 支持 | 不支持 | ? |
| 連接管理 | 靜態(tài)數(shù)組+單鏈表 | 動態(tài)數(shù)組,key交互 | Nginx更加穩(wěn)定高效。 |
| 超時處理 | 紅黑樹+巧妙的策略 | Alarm+for循環(huán) | ? |
| Accept處理 | 鎖+7/8閥值,支持mult? accept | 0.9策略,一次性aceept100個。 | ? |
| 狀態(tài)機 | | ||
| 后端處理 | 都支持多種協(xié)議,并且方便擴展,都支持負載均衡算法擴展。 | ||
| 擴展開發(fā) | 1、? 預定義鉤子2、? 控制反轉(zhuǎn) ? 3、? 豐富庫類 | 預定義鉤子 | ? |
| 反向代理 | 1、功能上,nignx和lighttpd都具有完整的反向代理功能。但nginx在這方面明顯優(yōu)于lighttpd,更加完整的細節(jié)考慮和優(yōu)化。主要體現(xiàn)在超時處理、文件上傳、輸入輸出的過濾、cache等等。2、性能上,Nginx稍優(yōu)于lighttpd。 | ||
| fastcgi | 功能上兩者差別不大,主要體現(xiàn)在性能上。在性能上,2000QPS以內(nèi),兩者性能差別不大,但高壓力下,兩者性能差別非常大。 | ||
| 頁面Cache | 支持proxy_cache。支持esi頁面cache | 不支持,需要額外開發(fā)。 | ? |
| 運維相關(guān) | 支持配置文件熱加載支持應(yīng)用程序熱加載 | 支持有限的配置文件熱加載 | ? |
通過上述對比分析,可以得出如下結(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,未來的主流。”
by xuliqiang
?
【本文首發(fā)于:搜索研發(fā)部官方博客】http://stblog.baidu-tech.com/?p=755 【關(guān)注百度技術(shù)沙龍】本文轉(zhuǎn)自百度技術(shù)51CTO博客,原文鏈接:http://blog.51cto.com/baidutech/743732,如需轉(zhuǎn)載請自行聯(lián)系原作者
總結(jié)
以上是生活随笔為你收集整理的Web server调研分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mac 键盘映射优化配置
- 下一篇: Rust 编程语言极简教程 --- 实例