Apache vs Nginx:基於實踐經驗的比較(外文翻譯)

本文來自Mobingi官方技術專欄,歡迎關注php

原文地址:Apache vs Nginx: Practical Considerations 前端

簡介

Apache和Nginx是世界上兩個最流行的開源web服務器,他們一塊兒支撐了互聯網上超過50%流量。他們兩個都支持多種負載模式而且能夠和其餘軟件服務集成在一塊兒提供全棧的web解決方案。nginx

雖然Apache和Nginx有不少共同點,但你不該該認爲它們是能夠徹底等價交換的。它們都·有本身各自的長處,瞭解這些有助於你從新評估你的web服務器的選擇。這篇文章致力於討論這兩個服務器在不一樣領域的不一樣表現。web

概覽

在咱們深刻討論Apache和Nginx的不一樣以前,讓咱們先簡單回顧一下這兩個項目的背景和特性。正則表達式

Apache

Apache HTTP 服務器於1995年由Robert McCool在Apache軟件基金會(1999創立)的領導下開發出來。由於它是這個基金會的原創項目而且也是這個基金會到目前爲止最有名的軟件,因此它常常被稱作「Apache」。算法

Apache從1996年開始直到如今一直是互聯網上最流行的web服務器軟件。由於流行,Apache基金會能夠經過提供完善的文檔以及系統集成支持給其餘軟件項目來獲取收益。apache

由於Apache的靈活性,性能和普遍支持,它常常被系統管理員選擇做爲web服務器。它能夠經過動態加載模塊拓展功能,而且能夠在不鏈接其餘第三方軟件的狀況下執行多種解釋型語言。後端

Nginx

在2002年,Igor Sysoev開始着手寫Nginx服務器用來解決C10K問題。C10K問題是web服務器的一個挑戰,要求一個web服務器在同一時刻能夠處理10000個鏈接請求。Nginx於2004年發佈最新版本,使用一種非同期的、基於事件處理機制來知足這一需求。緩存

由於佔用不多資源而且很是容易使用底端硬件擴展,Nginx開始變得流行。Nginx擅長提供靜態內容,而且被設計爲將須要動態內容處理的求轉發給其餘軟件以解決10K問題。安全

Nginx常常因爲它的低資源消耗以及高負載能力被服務器管理員選中,它的擁護者很是歡迎Nginx聚焦在web服務器以及代理服務器的核心特性上。

鏈接處理方式

Apache和Nginx的一個巨大的差距是他們實際處理鏈接和請求的方式。在不一樣的網絡流量條件下,這產生了兩個服務器很是不一樣的表現。

Apache

Apcahe提供了多種多進程工做模式(Apache稱這些爲MPMs, multi-processing modules)來處理請求,基本上,這樣可讓管理員很容易地變換服務器處理鏈接的方式。這些模式以下:

  • mpm_prefork:這種模式爲每個請求建立一個處理它的進程。每一個子進程同一時間只處理一個請求。若是請求數量小於進程數量,這種模式運行的很是快。不過當須要處理請求超出進程數量時,性能降低很是嚴重,因此對於不少應用場景這種模式不是一個好的選擇。每個進程都會耗損至關的內存,因此這種工做模式很難優化。當處理請求的內部組件不支持線程工做模式的狀況下,這種模式可能仍然是一個好的選擇。好比,PHP就不是線程安全的,因此這種工做模式被推薦爲與mod_php一塊兒運行的惟一安全模式。

  • mpm_worker: 這種模式建立的進程能夠管理本身線程。每個線程能夠單獨處理一個鏈接。由於與進程相比系統能夠建立更很是多的線程,也就意味着這種模式比prefork模式能處理更多的鏈接。一個新的鏈接會被立刻處理,而不須要等待一個空閒的進程來處理。

  • mpm_event: 這種模式和worker模式很像,不過它優化了keep-alive請求的處理方式。當使用worker模式的時候,一個鏈接(connection)會持有一個線程直到這個鏈接失效,無論這個鏈接上是否有請求過來。在event模式下,有專門的線程用來處理和保持鏈接,而後將請求轉發給其餘線程處理。這種方式可讓系統逃脫處理大量keep-alive請求的泥潭,使請求處理器獲得更快的執行。這個模式在Apache2.4版本中已被標記爲穩定(stable)狀態。

就像你看到的,Apache提供了一個靈活的結構能夠配置不一樣的鏈接和請求處理算法。這些工做模式表明了服務器的功能演進以及伴隨着互聯網格局變化而來的對大併發處理的需求的增加。

Nginx

Nginx在Apache以後來到這個舞臺,與生俱來就意識到須要面對大併發問。利用這方面的認識,Ngeix完全地由內到外地使用了非同期,非阻塞和事件驅動的鏈接處理算法。

Nginx生成工做進程,每個工做進程能夠處理上千個鏈接。工做進程經過實現一個快速的循環算法不斷的獲取並處理事件。從鏈接中分離出實際的請求處理工做,讓每個工做進程只有當新的事件發生是才與一個鏈接產生聯繫。

全部被工做進程處理的鏈接被放在事件循環(event loop)裏面,在這個循環裏,事件被非同期處理,使得處理變成一個非阻塞的過程。當鏈接關閉,鏈接從這個循環中刪除。

這種鏈接方式使得Nginx能夠利用有限的計算資源處理難以想象的大量請求。由於服務器是單線程的而且並不爲處理一個新的鏈接生成一個單獨的進程,因此內存和CPU的消耗趨於保持相對一致,甚至是在大併發的狀況下也如此。

靜態內容VS動態內容

在實際應用方面,Apache和Nginx之間最多見的比較是但請求到來時它們各自處理靜態內容和動態內容的方式。

Apache

Apache使用傳統的基於文件的方式處理靜態內容的請求。它的性能主要取決於它是被設定成哪工做模式(上面提到的)。

Apache也能夠處理動態內容,它經過嵌入一種處理語言到運行實例,在服務器內部就能夠處理動態內容,而不須要依賴外部組建。它經過使用可動態加載的模塊來開啓處理動態內容的進程。

Apache的可在服務器內部處理動態內容的能力意味着配置動態處理進程也比較簡單。不須要和一個附加的軟件交互而且當內容處理的需求發生變化時模塊也很容易替換。

Nginx

Ngnix自己沒有任何的動態處理能力。若是想執行PHP代碼或者爲請求生成動態內容,Nginx必須將請求傳遞給一個外部的處理器並等待渲染好的內容(一般是HTML文檔)而後再把它轉發給客戶端。

對於服務器管理員來講,這個意味着你必須配置Nginx和外部處理器之間的交互,這種交互必須基於一種Nginx能理解的協議(http, FastCGI, SCGI, uWSGI, memcache)。這可能會使事情變得稍微複雜,特別是試圖佔用容許鏈接的最大值時,由於已有了一個額外的鏈接用來轉發請求處處理器。

無論怎麼說,這個模式同時也有一些優勢。由於動態解釋器不是嵌入到Nginx的工做進程中的,因此它的開銷只限於處理動態內容,而靜態內容請求會被直接處理,Nginx只在須要的時候鏈接程序解釋器。Apache也能夠這樣工做,不過這樣的話就失去了咱們在前面說的優勢。

分佈式配置VS集中配置

對於服務器管理員來講,兩個服務器表現出來的最明顯的不一樣是是否容許文件夾級別的配置。

Apache

apache提供一個選項,容許對每一個目錄設置附加的配置。這個功能基於監測和實時翻譯內容所在文件夾上一個隱藏文件中的指令來完成。這個文件就是你們所熟知的.htacess。

由於.htacess文件就存在於請求內容所在文件夾。當處理一個請求的時候,Apache檢查每個文件的路徑,查找.htacess文件,執行裏面的命令,這使服務器的分散配置成爲可能。這個功能常常用於重寫URL,控制訪問甚至是緩存策略。

雖然上面說的例子能夠在Apache的主配置文件中設置。可是.htacess有一些重要的優點。首先,Apache在每次請求來的時候解釋指令,因此.htacess的配置會當即生效,而無需重啓服務器。其次它容許無權限的用戶來控制他們本身的web內容的某些方面,而無需修改Apache主配置文件。

這給某些web軟件,如內容管理系統(cms)提供了簡單方式來配資它們本身,而無需訪問主配置文件。這也一樣被用於共享主機提供商使他們在保持控制主要配置文件的同時讓客戶對他們本身的特定目錄有控制權限。

Nginx

nginx不會即時解釋.htacess文件,也不提供在主配置文件以外的任何支持目錄級別配置的技術。這可能相對於apache來講不夠靈活,但它卻有本身的優點。

最被你們熟知的相對於基於.htacess機制實現目錄級別配置的系統優點就是提升了性能。例如一個典型的Apache配置可能容許配置.htaccess在任何目錄,這樣的話每個請來訪問任何一個目錄下的資源的時候,服務器都會檢查這個目錄以及它全部的父目錄的.htaccess文件,若是在這個過程當中有一個或者多個.htaccess文件被找到,他們必須被讀取並解釋執行。Nginx不容許目錄重寫技術,每個請求過來Nginx只查找和讀取一個文件(假設文件能夠在約定目錄結構下找到),因此Nginx處理請求更快。

另外一個優點是關於安全的。分散的目錄級別的配置也同時把安全配置web服務的責任分散到了每個用戶(web應用管理員)頭上,他們可能沒法勝任這個任務。確保服務器管理員控制整個web服務器可預防一些把控制權轉交給他人所形成的安全隱患。

若是這些觀點與你產生共鳴,你應該時刻考慮是否能夠關閉解釋執行.htaccess文件。

文件VS基於URI的解釋執行

web服務器是如何解釋執行一個請求以及如何查找到與請求所匹配的系統資源的?這是另外一個這兩個服務器的不一樣之處。

Apache

Apache提供一種能夠把請求轉換成文件系統上的物理資源或者一個更抽象的URI的能力。整體上,之前的Aapache使用 或者塊配置,同時使用塊配置更抽象的資源。

由於Apache徹底是爲web服務器所設計。默認狀況下一個請求一般被解釋成一個文件資源請求。它在查找請求路徑中去掉域名和端口號後相對於document root的路徑下的真實文件。默認狀況下,文件結構會被以文檔樹的形式展現。

當請求沒有匹配到文件資源時,Apache提供不少可選項處理這種狀況。好比,一個alias命令可讓請求關聯到另外一個位置。用塊可使用URI代替文件系統工做。固然還可使用正則表達式,從而使基於文件系統的資源查找更加靈活。

雖然Apache同時具備操做底層文件系統和網站空間的能力,可是它很是依賴於文件系統,包括使用.htacces文件實現目錄級配置這,均可以被看做它的設計哲學。Apache docs警告用戶當請求能夠映射到底層文件系統時,最好不要使用基於URI的配置限制訪問。

Nginx

Nginx被當作web服務器和代理服務器而創造。考慮這兩種角色所須要的架構,它主要基於URI工做。只在須要的時候在將請求映射到文件系統。這能夠被看做是構造和解釋執行Nginx配置的方式。Nginx不提供任何關於文件系統目錄的配置,取而代之的是解析URI自己。

舉個例子,Nginx主要的配置塊是server和location塊。server配置塊用來解釋請求的域名部分,同時location配置塊負責匹配URI中域名和端口號後面的的部分。從這個觀點看,請求被解釋成一個URI請求,並非一個映射到文件系統上的文件。

對於靜態文件,全部的請求最終會映射到文件系統上的一個文件。首先,Nginx找到用於處理這個請求的server配置塊和location配置塊,而後組合document root目錄和URI,再根據指定配置作任何須要的調整。

這可能看起來很簡單,可是解析請求成URI而不是文件系統路徑使得Nginx能跟簡單地以web、mail和代理服務器方式工做,經過簡單的配置就以對應不一樣模式的request請求。Nginx不會檢查文件系統直到準備好提供被請求的內容,這解釋了爲何它沒有實現一種相似.htaccess的配置方式。

模塊

Nginx和Apache都支持經過模塊擴展服務器,可是他們的工做方式很是的不一樣。

Apache

Apache的模塊系統容許你在服務器的運行期間動態的加載或者卸載模塊。Apache的核心始終存在,而模塊能夠打開或關閉,以添加或者刪除掛載到server的主程序部分的附加功能。Apache經過這一個功能完成不少任務。因爲Apache平臺很是成熟,有不少用於擴展Apache的模塊存在。他們能夠用於改變Apache的一部分核心功能,例如mod_php就能夠嵌入PHP處理器到每個運行的工做進程中。

模塊不只僅只限於處理動態內容,它們還被用於URL重寫,認證客戶端,硬件化服務器,日誌,緩存,壓縮,代理,速率控制和編碼等等。動態模塊能夠很容容易的擴展核心功能而且並不須要太多額外的工做。

Nginx

Nginx也實現了一個模塊系統,可是它與Apache的實現方式很不一樣。在Nginx中,模塊不是動態加載的,它們必須被編譯到Nginx的核心程序中。

對於不少用戶來講,這可能讓他們感受Nginx不夠靈活。尤爲對那些只會安裝發佈版本而不熟悉經過編譯來管理維護本身軟件的用戶來講,這確實是一個問題。不過發佈版本老是傾向於包含使用最普遍的模塊,若是你須要一個非標準的模塊,你必需要本身編譯你的Nginx服務器軟件。

編譯Nginx的模塊仍是很是有用的,他們容許指出哪些功能你不想放在服務器中,而哪些功能你須要使用。不少用戶也認爲這樣更加安全,由於那些未經挑選的組件不會掛載到服務器中。無論怎樣,若是你的服務器已經配置好了,它極可能是妥協後的產物。

Nginx模塊的功能不少都和Apache模塊類似。例如,Nginx模塊能夠提供代理服務,壓縮,速率控制,日誌,重寫,地理位置,認證,編碼,流媒體和郵件功能。

支持、兼容性、生態系統和文檔

考慮這些的要點在於,你的應用主要作什麼樣的處理,須要配合哪些其餘軟件使用。

Apache

由於Apache已經流行了很長時間,對它的支持幾乎是廣泛存在的。有不少官方的或者第三方的文檔說明核心服務器以及如何掛載其餘軟件到核心服務器。

Nginx

由於Nginx的高性能,愈來愈多的用戶選擇使用Nginx,愈來愈來越多的軟件開始支持Nginx。可是在不少關鍵領域Nginx還須要追趕Apache的腳步。

在過去,找到一份全面的關於Nginx的文檔很難。由於大部分早期的開發是由俄羅斯人完成,文檔也是俄語的。伴隨着這個項目的普及,產生了不少文檔,而且在Nginx的網站以及第三方站點上有很是多的管理員資源。

出於對第三方軟件的尊重,技術支持文檔變得更加易讀,而且Nginx軟件包維護者開始在某些狀況下容許Apache和Nginx之間配置的自由轉換。就算沒有技術支持,配置Nginx服務器和可選軟件一塊兒工做也一般很是簡單直接,正如它項目文檔裏描述的那樣。

Apache和Nginx一塊兒使用

在咱們瞭解了Apache和Nginx的優點和劣勢以後,你可能已經想好了哪個服務器更符合你的需求。不管如何,不少用戶發現能夠經過同時使用它們而得到它們兩個的全部優勢。

這種組合的傳統配置是把Nginx配置到Apache的前端做爲一個反向代理服務器。這使Nginx處理來自客戶端的全部請求。這樣得益於Nginx的快速處理能力,能夠同時處理很是大量的鏈接。

對於Nginx擅長靜態內容,文件會快速且直接的發送給客戶端。對於動態內容,好比PHP文件,Nginx將把請求發送給Apache,Apache能夠處理請求,並渲染結果。而後Nginx能夠將結果發回給客戶端。

這種設置在大多數狀況下都工做的很好。由於這讓Nginx像一臺排序機器同樣工做,Nginx會處理全部的請求而後把它不能處理的請求轉發出去,經過減小Apache處理的請求數量,能夠緩解當Apache的處理進程或者線程被佔用時產生的阻塞。

這樣配置也使你能夠根據需求添加額外的後端服務器來擴容服務器。Nginx能夠很容易的配置成轉發請求到服務器池,這樣能夠加強服務器性能和容錯能力。

總結

正如你看到的,Apache和Nginx都是強大,靈活的服務器軟件。哪一個服務器最好,取決於你的應用服務的特殊需求,以及對它們在你指望的運行條件下的測試結果。

在兩個服務器以前存在着不少不一樣,這些差別的存在會實實在在地影響性能,負載,以及配置應用運行起來的時間成本。然而,這是一系列權衡結果,不該該被隨意決定。最後我要說,沒有萬能的web服務器,因此選擇適合你的項目的解決方案。


這是我第一次翻譯英文文檔,不少詞彙找不到合適的中文表達,也可能有一些專業技術詞彙沒有和中文技術詞彙精確對應,請你們多多指正。

相關文章
相關標籤/搜索