Nginx vs Apache

oschina發表於2014-06-03

  什麼是Nginx代理代理伺服器,它和Apache相比又有什麼區別呢?你又該如何選擇使用呢,用其中一個還是兩者都用?我們將會在這裡探索一下這些問題的答案。

  Apache伺服器從1995年就開始使用了。相比其他產品,Apache伺服器是使用最多的,其次是微軟的IIS伺服器。

  由於開源的Apache伺服器已經被使用多年,並且有眾多的使用者,人們開發出了很多的模組來擴充套件它的功能,其中的大多數模組也是開源的。舉例來說,一個比較常見的配置是使用Apache來為靜態頁面提供服務,並使用mod_jk模組來執行Tomcat上的Java和JSP程式碼,以便使程式具有互動功能。另一個例子是使用mod_php模組來執行php程式碼,而不用去使用cgi。

  但是,Apache在高負載的情況下表現的差強人意,原因是它需要去執行新的程式,因此要消耗更多的記憶體。同時,他還要產生新的執行緒來與其他的執行緒競爭記憶體和CPU。當程式的流量達到了管理員設定的上限時,Apache會拒絕新的連線。

  Nginx 是一個開源的伺服器,用來解決一些Apache在效能和擴充套件性方面的問題的。Nginx是開源並且免費的,但是如果你購買了它的Nginx Plus版本的話是可以享受到服務支援的。

  Nginx 聲稱它的伺服器是用來解決C10K問題(出自Daniel Kegel發表的一篇關於如何使一個伺服器處理10000個連線——假設的作業系統的上限的論文)的。在他的論文中,他引用了另一篇由Dean Gaudet寫的論文,其中寫到“你們為什麼不使用一個像Zeus那樣的選擇/事件(select/event)為基礎的模型呢?很明顯那是最快的”。

  Nginx 確實是以事件為基礎的(event-based)。他們把他們的架構稱為“事件驅動且非同步”(event-driven and asynchronous)。Apache 依賴於程式和執行緒。那麼,區別是什麼呢?

 Apache是如何工作的,為什麼會有極限

  Apache通過建立程式和執行緒來處理其他的連線。管理員可以通過設定來控制伺服器所能允許的最大程式數量。這個配置因機器的可用記憶體而異。過多的程式會耗盡記憶體從而使得機器使用磁碟上的交換記憶體,這嚴重的降低了效能。而且,當達到程式的上限之後,Apache會拒絕新的連線。

  Apache可以通過設定來執行在pre-forked 模式或worker multi-process 模式(MPM)。當其他的使用者連線時,兩種方式都會建立新的程式。區別在於,pre-forked模式為每一個程式建立一個執行緒,用來處理一個使用者的請求。worker模式也建立新的程式,但是每一個程式至少有一個執行緒,每一個執行緒用來處理單個使用者的單個請求。所以,一個worker mode 的程式處理至少一個連線,而一個per-fork 模式的程式只處理一個連線。

  相比於forked 模式,worker 模式使用更少的記憶體,原因是程式比執行緒消耗更多的記憶體,執行緒只是執行在程式中的程式碼。

  此外,worker模式不是執行緒安全的。這意味著如果你使用像mod_php這樣的非執行緒安全的模組來服務php頁面時,你需要使用pre-forked模式,因此要消耗更多的記憶體。所以,當選擇模組和配置伺服器時,你必須要面對是執行緒還是程式更優的問題以及一些約束的問題。

  在調整Apache時的一個限制因素是記憶體以及當爭奪同一個CPU和記憶體時潛在的執行緒死鎖問題。如果一個執行緒停止了,使用者會一直處於等待頁面出現的狀態,直到程式將該執行緒回收,以便可以發回頁面。如果一個執行緒發生了死鎖,它不知道如何重啟,因此會一直處於卡住狀態。

 Nginx

  和Apache相比,Nginx的工作方式有很大不同,主要是在於它如何處理執行緒。

  Nginx並不會為每一個的web請求建立新的程式,相反,管理員可以配置Nginx主程式的工作程式的數量(一個常見的做法是為每一個CPU配置一個工作程式)。所有這些程式都是單執行緒的。每一個工作程式可以處理數千個併發的請求。它通過一個執行緒來非同步的完成了這些工作,而沒有使用多執行緒的程式設計模型。

  Nginx還拆分了快取載入器(cache loader)和快取管理器(cache manager)程式用來從磁碟中讀取資料並將其載入到快取中,當快取直接讀取的時候快取過期。

  Nginx有一系列的模組組成,這些模組在編譯的時候就被包含進去了。這意味著,使用者下載原始碼並選擇他們要編譯的模組。這些模組中包括連線後端應用伺服器,負載均衡,代理伺服器以及其他。並沒有PHP的模組,因為Nginx可以自己編譯PHP程式碼。

  這裡有一張圖描述了Nginx的架構,該圖來自Andrew Alexeev的深入分析Nginx及其工作方式。

  從這個圖表中我們可以看出,Nginx使用FastCGI程式來執行Python,Ruby以及其他程式碼,使用Memcached物件快取系統。工作程式為HTTP請求載入ht_core Nginx程式。我們還可以看到,Nginx和Windows以及Linux核心的功能緊密的整合在了一起,以便提升效能。這些核心功能已經經過長時間的改良,而Nginx正是利用了這一點。

  Nginx聲稱是事件驅動,非同步且無阻塞的。“事件(Event)”指的是一個使用者的連線。“非同步(Asynchronous)”指的是它一次處理多個使用者連線的使用者互動。“無阻塞(Non-blocking)”指的是它不會由於CPU處於忙狀態而停止磁碟的I/O,在這種情況下,它會處理其他事件,直到I/O資源得到釋放。

 Nginx 與 Apache 2.4 MPM

  Apache 2.4包含多路處理事件模組(MPM event module)。它能處理在非同步方式下的連線型別,Niginx同樣也能做,但是在方式上是不一樣的。目的是在負載增長的時候,壓縮對記憶體的需求。

  在早期的版本中,Apache 2.4包含工作者(worker)和前複製叉(pre-forked)模式,除了我們之前提到那些,還包括已經被新增的mpm_event_module(Apache MPM event module),它被用來解決為了保活而等待這個連線的執行緒問題(等待是因為這個連線是使用者額外的請求)。MPM致力於一個執行緒能處理套接字(sockets)中監聽(listening)和保活(keep-alive)這兩者的狀態。這個關於地址的記憶體問題與舊版本的Apache相關,通過減少執行緒數量以及程式的建立次數。正是這一點,管理員可能要下載Apache的原始碼並且包括mem_event_module,還要編譯Apache,用以代替正在使用的二進位制發行版。

  Apache的MPM事件模型與Nginx的並不完全相同,這是因為當Apache接收到新的請求(請求的數量受到管理員所設定的限制)時,它就會產生新的程式。Nginx不會為每個使用者建立多個程式。在Apache 4.2上做了如下改進:與Apache通常的工作者模式相比 ,這個版本里所建立的服務程式將會生成更少的執行緒。這是因為一個執行緒可以處理多個連線,而不是每個連線需要一個程式為其提供服務。

  既使用Nginx,又使用Apache

  Apache是因為其功能強大而出名的,而Nginx是因為其響應速度快而著稱的。這就意味著Nginx在靜態內容的服務上要相對快些,不過,Apache可以使用模組來執行後臺應用伺服器,而且還可以執行指令碼語言。

  Apache和Nginx都可以用作代理伺服器,不過通常我們會把Nginx用作代理伺服器,而把Apache用作後臺伺服器。Nginx包含了 先進的負載均衡和內容緩衝功能。當然,Apache伺服器的部署數量巨大。為了充分發揮Apache伺服器的效能,就需要有負載均衡器。Apache可以使用自身所包含負載均衡模組,另外,還可以使用基於硬體的負載均衡器。

  另一種使用方法是給Nginx配置獨立的 php-fpm應用,我們認為 php-fpm是一個應用,這是因為它不是執行期間可以裝載的.dll或者.so,而是與Apache的模組使用方法相同。Ngnix使用php-fpm(FastCGI程式管理器)來處理php指令碼,這就使得Nginx具有生成非靜態內容的功能。

 什麼時候更適合用Apache?

  Apache 具有內建支援PHP,Python,Perl等語言的能力。例如,mod_perl和mod_php模組可以用來在Apache的程式中處理PHP和Perl的程式碼。mod_python比使用CGI或FastCGI更高效,因為它不需要為每一個請求載入Python的直譯器。對mod_rails和mod_rack模組來說也是一樣,這些模組使得Apache可以執行Ruby on Rails。這些程式在Apache的程式中執行的更快一些。

  所以,如果你的網站主要是用Python或Ruby開發的,你最好使用Apache,因為Apache不需要使用CGI。對於PHP來說,用誰就無所謂了,因為Nginx也支援內建的PHP了。

  我們在這裡給出了Nginx和Apache之間的一些差異,以及我們該如何去考慮使用其中的一個或者兩者都用,以及哪一個更加適合你的需求。另外,我們也討論了Apache2.4已經把Nginx線上程和程式管理方面的一些提升加入到了Apache的伺服器中。所以,你可以為你的需求找到最好的解決方案的。

  原文地址:https://anturis.com/blog/nginx-vs-apache/

相關文章