天天看點

web 伺服器-Nginx 與 Lighttpd對比分析

簡單可依賴的架構首先需要有一個簡單可依賴的前端WebServer叢集。本文通過深入調研目前主流的異步web伺服器Lighttpd和Nginx,從業界使用情況、架構原理、擴充開發、功能對比、性能對比等多個方面進行分析。

調研分析

業界相關

從業界使用情況來看,最新Web Server使用情況的資料如下:Nginx的使用率是6.6%,Lighttpd的使用率是0.51%。

web 伺服器-Nginx 與 Lighttpd對比分析

從文檔來看,nginx中文相關文檔越來越多。來自最新的百度搜尋資料顯示,nginx的網頁數量是lighttpd的10倍。目前國内對于Nignx核心深入研究的人越來越多,有淘寶、sina、騰訊等許多大公司的技術人員參與研究,并進行相關的技術交流。對于Lighttpd的研究,目前主要是公司内部和一些學生。

從業界的點評來看,國内外基本上結論如下:

  • 兩者都是異步WebServer,都采用了狀态機。本質上是相同的。
  • Nginx穩定度高于Lighttpd。Lighttpd一直存在一定的記憶體洩漏。
  • 性能上兩者都非常優秀,Nginx有一定優勢。
  • Nginx在綜合性能上更加優秀,更有可能成為未來的apache。

從社群活躍度來看,Nginx每月2到3個三位版本釋出。Lighttpd3位版本更新較慢,目前1.5的版本基本上沒有更新過。同時Nginx有豐富的第三方庫類。

架構原理

代碼層次

Nginx的代碼量10W行,Lighttpd是5W左右。相對來說,Nginx的代碼層次結構更加分明,具體代碼結構如下:

web 伺服器-Nginx 與 Lighttpd對比分析

Nginx和lighttpd都是采用C語言編寫的,對于基礎資料結構都有一定的處理。Nginx中關于資料結構的代碼主要放在core檔案夾裡面。

web 伺服器-Nginx 與 Lighttpd對比分析

Nginx主要的基礎代碼有:array、string、buf、file、hash、md5、記憶體池、隊列、紅黑樹、time、共享鎖等。這些資料結構對于擴充開發都非常有幫助。Lighttpd有一定的基礎資料封裝,但相對沒有那麼明顯的設計。目前觀察到的基礎代碼有:bitset、buffer等。

記憶體管理是所有C程式中非常值得關注的一點。Lighttpd在記憶體管理上沒有做特殊的考慮,基本上都是采用系統記憶體管理函數,比如malloc/calloc等。在擴充開發中的記憶體也需要擴充子產品自己考慮。Nginx在記憶體管理上提供了兩種方式:1、原生malloc等的二次封裝。2、記憶體池。在nginx内部大量的使用記憶體池。在擴充開發中也能直接調用記憶體池進行記憶體管理。此外,nginx還内置了對tcmalloc的支援。把記憶體優化做到極緻。

架構層次

從總體架構來看,Nginx/Lighttpd都屬于master+worker的工作模型。

web 伺服器-Nginx 與 Lighttpd對比分析

但nginx相比lighttpd,在細節上處理的更加優化,具體可以從幾個方面來談

1、  配置檔案熱加載。Nginx從設計開始就支援配置檔案熱加載,甚至程式的熱加載。Lighttpd本身不支援,目前業界有采用擴充方式,比如說lua,可以實作部配置設定置熱加載。

2、  強大的master程序,實作worker程序和master程序的各司其職。Lighttpd的master程序在fork完worker程序後,就單獨的等待worker程序的結束(或者在worker程序結束後再建立新的worker子程序)。Nginx的master程序負責對worker子程序的管理,并通過socket pair通信方式實作熱配置檔案更新、優雅重新開機、熱應用程式更新等功能。

3、  線程鎖。Lighttpd在程序之外還啟動了線程進行相關方面的工作,這會對lighttpd的性能帶來一定影響。Nginx内部雖然提供了對線程模式的支援,但在主推的程序模式中不會出現額外的線程。

4、  多核機器優化,cpu affinity。Nginx設計中考慮了對多核機器的優化方案,能降低程序在不同cpu之間的切換次數,進而提升性能。

逾時處理

Lighttpd的逾時處理原理非常簡單:通過alarm信号量來實作的。每1s出發一個alarm信号,進而切換到逾時處理函數。該函數也非常簡單:循環簡單目前所有連接配接的讀和寫,如果事件逾時了,則直接close掉。這會有幾個問題:

1、  連接配接非常多的時候。逾時處理還是會非常耗事件的。随着連接配接數而遞增。

2、  在不可重入的函數中出發alarm的時候,有可能出現意想不到的問題。

3、  需要輪詢。

Nginx在逾時處理上實作的巧妙的多:采用資料結構和巧妙的政策來實作。

1、  使用紅黑樹來存放定時器的相關資料。紅黑樹的重要特點是:插入删除都會在O(logN)完成,同時具有優秀的查找性能。是以很多C++的庫(map)等都用到了它。

2、  通過紅黑樹計算出目前節點的逾時時間差,使用這個時間差作為調用多路複用I/O操作的參數,當函數傳回,隻可能是I/O事件被觸發,或者逾時。

3、  處理完I/O事件之後,得到處理前後的時間差,根據這個時間差依次檢視紅黑樹中哪些定時器可以被處理。

這也是在高壓力下,Nginx更優于Lighttpd的一個重要原因。

Accept處理

Lighttpd中對于Accept的處理有幾個特點:1、不加鎖。2、連接配接處理達到0.9的時候會禁止接收新的連接配接。3、1次性accpet 100個。這樣有一個好處, 假如伺服器監聽fd是每次觸發隻接收一個新的連接配接, 那麼效率是比較低的,不如每次被觸發的時候”盡力”的去接收, 一直到接收了100個新的連接配接或者沒有可接收的連接配接之後才傳回。4、提供了fdwaitqueue。在fd不夠用的時候備用。

Nginx:1、程序加鎖,避免驚群,同時控制了擷取accpet的機率,一定程度上控制各個子程序之間的請求數目。2、7/8閥值。連接配接數目達到最大連接配接數的7/8的時候,該程序将擷取不到對應的accept鎖。進而進入安全控制階段。3、提供了multi_accept指令,在開啟的情況下也和lighttpd一樣盡可能的多accept。

狀态機

Lighttpd和nginx都是狀态機驅動模型,兩者之間主要展現在細節的差異性上。

  1. Nginx對整個狀态進行了分類,分成預處理、狀态機、filter流程三個明顯的階段。
  2. Lighttpd的狀态機相對簡單固定。Nginx則相對靈活。
  3. Nginx的大部分處理狀态都是可以擴充的并且可中斷的。Lighttpd在部分狀态中也可以擴充的。
  4. 耦合程度。nginx狀态處理函數之間的耦合緊密,狀态切換時的下一步處理由狀态處理函數來決。而lighttpd将狀态切換的動作放在狀态機裡,各個狀态處理函數不關心下一步需要做什麼,狀态之間的耦合小。但同時會對擴充性帶來一些問題,比如說subrequest的實作。

後端處理

Nginx針對不同的後端處理方式進行了封裝,提供upstream來支援不同的協定(HTTP/FASTCGI/Memcache),提供擴充來支援不同的負載均衡算法。同樣的Lighttpd在新版中也對不同的後端協定進行了封裝,并提供了不同可供選擇的負載均衡算法。

從原理層次來看,兩者在後端處理上的思路是基本一緻的。更多的對比需要從功能和性能上來對比。

擴充開發

Nginx和Lighttpd都支援擴充,Lighttpd是通過預留系統鈎子來實作的,相對來說不夠靈活,如果有一些特殊的修改則不得不修改源碼。Nginx則通過預留系統鈎子和控制反轉結合,進而能夠實作更多的功能。是以,nginx擴充的靈活性高于Lighttpd。

總結如下:

1、  nginx不支援動态擴充子產品。

2、  擴充開發上,nginx更加靈活。提供了多種擴充切入方式。

3、  Nginx提供了豐富的類庫,友善擴充開發。

功能對比

反向代理

對比分析如下:

1、  性能。

  • 同等壓力下,nginx的cpu消耗要低于lighttpd。但整體差别不大。
  • 極限壓力下,nginx處理能力高于lighttpd。原因未知。

2、  功能。

功能點 Lighttpd Nginx 備注
靈活的反向代理方式 支援 支援 都非常好
正則 支援 支援
自定義header頭 部分支援 支援 目前gm有庫支援IP的傳遞
負載均衡 支援 支援
逾時處理 支援 支援連接配接、讀寫等
故障處理 支援 支援
Cache 不支援 支援
檔案上傳 未知 支援,可配置,有優化 Transmit不支援
輸出過濾 不支援 支援 頭部過濾和内容過濾。

結論:

1、功能上,nignx和lighttpd都具有完整的反向代理功能。但nginx在這方面明顯優于lighttpd,更加完整的細節考慮和優化。主要展現在逾時處理、檔案上傳、輸入輸出的過濾、cache等等。

2、性能上,Nginx稍優于lighttpd。

Fastcgi支援

Nginx和lighttpd在Fastcgi方面功能上基本上相同,主要調研是從性能上對比。

web 伺服器-Nginx 與 Lighttpd對比分析

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

從性能資料來看,2000QPS以内,兩者性能差别不大,但高壓力下,兩者性能差别非常大。甚至有可能達到20%cpu差别。

頁面Cache和運維

Lighttpd目前暫無頁面Cache的支援。Nginx從設計之初就考慮了更改Cache。甚至有單獨的Cache管理程序。

從功能上來看,目前Nginx已經支援proxy cache和ssl filter,并且實作了對esi cache的支援。

從運維上來看,Nginx支援配置熱加載,支援程式熱加載。更适合完成24*365的全天候不間斷服務。

總結

對比點彙總整理後如下

對比點 Nginx Lighttpd 備注
市場占有率 6.6% 0.5%
文檔

百度文檔10:1Google文檔 1:1           

國内研究人員nginx>lighttpd

業界點評 更加看好Nginx
代碼量 10W 5W Nginx的代碼結構層次較好。
基礎資料結構 array、string、buf、file、hash、md5、記憶體池、隊列、紅黑樹、time、共享鎖 bitset、buffer 豐富的庫類對擴充開發有很大幫助
記憶體管理 原生malloc、記憶體池、支援tcmalloc 原生malloc
配置檔案熱加載 支援 不支援
程序模型 Master負責管理,worker負責處理請求,各司其職。 Master簡單。Worker複雜
程序額外線程 存線上程鎖
多核機器優化 支援 不支援
連接配接管理 靜态數組+單連結清單 動态數組,key互動 Nginx更加穩定高效。
逾時處理 紅黑樹+巧妙的政策 Alarm+for循環
Accept處理 鎖+7/8閥值,支援mult  accept 0.9政策,一次性aceept100個。
狀态機
  1. Nginx對整個狀态進行了分類,分成預處理、狀态機、filter流程三個明顯的階段。
  2. Lighttpd的狀态機相對簡單固定。Nginx則相對靈活。
  3. Nginx的每一個狀态都是可以擴充的并且可中斷的。Lighttpd在部分狀态中也可以擴充的。
  4. 耦合程度。nginx狀态處理函數之間的耦合緊密,狀态切換時的下一步處理由狀态處理函數來決定ligty将狀态切換的動作放在狀态機裡,各個狀态處理函數不關心下一步需要做什麼,狀态之間的耦合小。
後端處理 都支援多種協定,并且友善擴充,都支援負載均衡算法擴充。
擴充開發

1、  預定義鈎子2、  控制反轉           

3、  豐富庫類

預定義鈎子
反向代理 1、功能上,nignx和lighttpd都具有完整的反向代理功能。但nginx在這方面明顯優于lighttpd,更加完整的細節考慮和優化。主要展現在逾時處理、檔案上傳、輸入輸出的過濾、cache等等。2、性能上,Nginx稍優于lighttpd。
fastcgi 功能上兩者差别不大,主要展現在性能上。在性能上,2000QPS以内,兩者性能差别不大,但高壓力下,兩者性能差别非常大。
頁面Cache 支援proxy_cache。支援esi頁面cache 不支援,需要額外開發。
運維相關 支援配置檔案熱加載支援應用程式熱加載 支援有限的配置檔案熱加載

通過上述對比分析,可以得出如下結論:

“lighttpd和nginx一樣具有非常好的架構,但在資料結構、記憶體管理都多個細節方面處理nginx考慮更加完善。如果說lighttpd是異步web server的先驅,那麼nginx則是對lighttpd做了整體的優化的。而這些優化是全面的,根本性質的。無法簡單的通過更新lighttpd來實作。因為nginx從一開始設計就希望做成一個完美的異步web server。nginx從event、跨平台、基礎資料結構都很多細節方面進行了考慮和優化。應該來說,nginx必定是未來的apache,未來的主流。”

by xuliqiang

繼續閱讀