什么是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的服務器中。所以,你可以為你的需求找到最好的解決方案的。
掃碼二維碼 獲取免費視頻學習資料
- 本文固定鏈接: http://phpxs.com/post/2014/
- 轉載請注明:轉載必須在正文中標注并保留原文鏈接
- 掃碼: 掃上方二維碼獲取免費視頻資料