什么是Nginx代理代理服務(wù)器,它和Apache相比又有什么區(qū)別呢?你又該如何選擇使用呢,用其中一個還是兩者都用?我們將會在這里探索一下這些問題的答案。
Apache服務(wù)器從1995年就開始使用了。相比其他產(chǎn)品,Apache服務(wù)器是使用最多的,其次是微軟的IIS服務(wù)器。
由于開源的Apache服務(wù)器已經(jīng)被使用多年,并且有眾多的用戶,人們開發(fā)出了很多的模塊來擴(kuò)展它的功能,其中的大多數(shù)模塊也是開源的。舉例來說,一個比較常見的配置是使用Apache來為靜態(tài)頁面提供服務(wù),并使用mod_jk模塊來運(yùn)行Tomcat上的Java和JSP代碼,以便使程序具有交互功能。另一個例子是使用mod_php模塊來執(zhí)行php代碼,而不用去使用cgi。
但是,Apache在高負(fù)載的情況下表現(xiàn)的差強(qiáng)人意,原因是它需要去運(yùn)行新的進(jìn)程,因此要消耗更多的內(nèi)存。同時,他還要產(chǎn)生新的線程來與其他的線程競爭內(nèi)存和CPU。當(dāng)進(jìn)程的流量達(dá)到了管理員設(shè)置的上限時,Apache會拒絕新的連接。
Nginx 是一個開源的服務(wù)器,用來解決一些Apache在性能和擴(kuò)展性方面的問題的。Nginx是開源并且免費(fèi)的,但是如果你購買了它的Nginx Plus版本的話是可以享受到服務(wù)支持的。
Nginx 聲稱它的服務(wù)器是用來解決C10K問題(出自Daniel Kegel發(fā)表的一篇關(guān)于如何使一個服務(wù)器處理10000個連接——假設(shè)的操作系統(tǒng)的上限的論文)的。在他的論文中,他引用了另一篇由Dean Gaudet寫的論文,其中寫到“你們?yōu)槭裁床皇褂靡粋€像Zeus那樣的選擇/事件(select/event)為基礎(chǔ)的模型呢?很明顯那是最快的”。
Nginx 確實(shí)是以事件為基礎(chǔ)的(event-based)。他們把他們的架構(gòu)稱為“事件驅(qū)動且異步”(event-driven and asynchronous)。Apache 依賴于進(jìn)程和線程。那么,區(qū)別是什么呢?
Apache是如何工作的,為什么會有極限
Apache通過創(chuàng)建進(jìn)程和線程來處理其他的連接。管理員可以通過設(shè)置來控制服務(wù)器所能允許的最大進(jìn)程數(shù)量。這個配置因機(jī)器的可用內(nèi)存而異。過多的進(jìn)程會耗盡內(nèi)存從而使得機(jī)器使用磁盤上的交換內(nèi)存,這嚴(yán)重的降低了性能。而且,當(dāng)達(dá)到進(jìn)程的上限之后,Apache會拒絕新的連接。
Apache可以通過設(shè)置來運(yùn)行在pre-forked 模式或worker multi-process 模式(MPM)。當(dāng)其他的用戶連接時,兩種方式都會創(chuàng)建新的進(jìn)程。區(qū)別在于,pre-forked模式為每一個進(jìn)程創(chuàng)建一個線程,用來處理一個用戶的請求。worker模式也創(chuàng)建新的進(jìn)程,但是每一個進(jìn)程至少有一個線程,每一個線程用來處理單個用戶的單個請求。所以,一個worker mode 的進(jìn)程處理至少一個連接,而一個per-fork 模式的進(jìn)程只處理一個連接。
相比于forked 模式,worker 模式使用更少的內(nèi)存,原因是進(jìn)程比線程消耗更多的內(nèi)存,線程只是運(yùn)行在進(jìn)程中的代碼。
此外,worker模式不是線程安全的。這意味著如果你使用像mod_php這樣的非線程安全的模塊來服務(wù)php頁面時,你需要使用pre-forked模式,因此要消耗更多的內(nèi)存。所以,當(dāng)選擇模塊和配置服務(wù)器時,你必須要面對是線程還是進(jìn)程更優(yōu)的問題以及一些約束的問題。
在調(diào)整Apache時的一個限制因素是內(nèi)存以及當(dāng)爭奪同一個CPU和內(nèi)存時潛在的線程死鎖問題。如果一個線程停止了,用戶會一直處于等待頁面出現(xiàn)的狀態(tài),直到進(jìn)程將該線程回收,以便可以發(fā)回頁面。如果一個線程發(fā)生了死鎖,它不知道如何重啟,因此會一直處于卡住狀態(tài)。
Nginx
和Apache相比,Nginx的工作方式有很大不同,主要是在于它如何處理線程。
Nginx并不會為每一個的web請求創(chuàng)建新的進(jìn)程,相反,管理員可以配置Nginx主進(jìn)程的工作進(jìn)程的數(shù)量(一個常見的做法是為每一個CPU配置一個工作進(jìn)程)。所有這些進(jìn)程都是單線程的。每一個工作進(jìn)程可以處理數(shù)千個并發(fā)的請求。它通過一個線程來異步的完成了這些工作,而沒有使用多線程的編程模型。
Nginx還拆分了緩存加載器(cache loader)和緩存管理器(cache manager)進(jìn)程用來從磁盤中讀取數(shù)據(jù)并將其加載到緩存中,當(dāng)緩存直接讀取的時候緩存過期。
Nginx有一系列的模塊組成,這些模塊在編譯的時候就被包含進(jìn)去了。這意味著,用戶下載源碼并選擇他們要編譯的模塊。這些模塊中包括連接后端應(yīng)用服務(wù)器,負(fù)載均衡,代理服務(wù)器以及其他。并沒有PHP的模塊,因?yàn)镹ginx可以自己編譯PHP代碼。
這里有一張圖描述了Nginx的架構(gòu),該圖來自Andrew Alexeev的深入分析Nginx及其工作方式。
從這個圖表中我們可以看出,Nginx使用FastCGI進(jìn)程來執(zhí)行Python,Ruby以及其他代碼,使用Memcached對象緩存系統(tǒng)。工作進(jìn)程為HTTP請求加載ht_core Nginx進(jìn)程。我們還可以看到,Nginx和Windows以及Linux內(nèi)核的功能緊密的集成在了一起,以便提升性能。這些內(nèi)核功能已經(jīng)經(jīng)過長時間的改良,而Nginx正是利用了這一點(diǎn)。
Nginx聲稱是事件驅(qū)動,異步且無阻塞的?!笆录?Event)”指的是一個用戶的連接?!爱惒?Asynchronous)”指的是它一次處理多個用戶連接的用戶交互?!盁o阻塞(Non-blocking)”指的是它不會由于CPU處于忙狀態(tài)而停止磁盤的I/O,在這種情況下,它會處理其他事件,直到I/O資源得到釋放。
Nginx 與 Apache 2.4 MPM
Apache 2.4包含多路處理事件模塊(MPM event module)。它能處理在異步方式下的連接類型,Niginx同樣也能做,但是在方式上是不一樣的。目的是在負(fù)載增長的時候,壓縮對內(nèi)存的需求。
在早期的版本中,Apache 2.4包含工作者(worker)和前復(fù)制叉(pre-forked)模式,除了我們之前提到那些,還包括已經(jīng)被添加的mpm_event_module(Apache MPM event module),它被用來解決為了?;疃却@個連接的線程問題(等待是因?yàn)檫@個連接是用戶額外的請求)。MPM致力于一個線程能處理套接字(sockets)中監(jiān)聽(listening)和?;睿╧eep-alive)這兩者的狀態(tài)。這個關(guān)于地址的內(nèi)存問題與舊版本的Apache相關(guān),通過減少線程數(shù)量以及進(jìn)程的創(chuàng)建次數(shù)。正是這一點(diǎn),管理員可能要下載Apache的源代碼并且包括mem_event_module,還要編譯Apache,用以代替正在使用的二進(jìn)制發(fā)行版。
Apache的MPM事件模型與Nginx的并不完全相同,這是因?yàn)楫?dāng)Apache接收到新的請求(請求的數(shù)量受到管理員所設(shè)置的限制)時,它就會產(chǎn)生新的進(jìn)程。Nginx不會為每個用戶創(chuàng)建多個進(jìn)程。在Apache 4.2上做了如下改進(jìn):與Apache通常的工作者模式相比 ,這個版本里所創(chuàng)建的服務(wù)進(jìn)程將會生成更少的線程。這是因?yàn)橐粋€線程可以處理多個連接,而不是每個連接需要一個進(jìn)程為其提供服務(wù)。
既使用Nginx,又使用Apache
Apache是因?yàn)槠涔δ軓?qiáng)大而出名的,而Nginx是因?yàn)槠漤憫?yīng)速度快而著稱的。這就意味著Nginx在靜態(tài)內(nèi)容的服務(wù)上要相對快些,不過,Apache可以使用模塊來運(yùn)行后臺應(yīng)用服務(wù)器,而且還可以運(yùn)行腳本語言。
Apache和Nginx都可以用作代理服務(wù)器,不過通常我們會把Nginx用作代理服務(wù)器,而把Apache用作后臺服務(wù)器。Nginx包含了 先進(jìn)的負(fù)載均衡和內(nèi)容緩沖功能。當(dāng)然,Apache服務(wù)器的部署數(shù)量巨大。為了充分發(fā)揮Apache服務(wù)器的效能,就需要有負(fù)載均衡器。Apache可以使用自身所包含負(fù)載均衡模塊,另外,還可以使用基于硬件的負(fù)載均衡器。
另一種使用方法是給Nginx配置獨(dú)立的 php-fpm應(yīng)用,我們認(rèn)為 php-fpm是一個應(yīng)用,這是因?yàn)樗皇菆?zhí)行期間可以裝載的.dll或者.so,而是與Apache的模塊使用方法相同。Ngnix使用php-fpm(FastCGI進(jìn)程管理器)來處理php腳本,這就使得Nginx具有生成非靜態(tài)內(nèi)容的功能。
什么時候更適合用Apache?
Apache 具有內(nèi)建支持PHP,Python,Perl等語言的能力。例如,mod_perl和mod_php模塊可以用來在Apache的進(jìn)程中處理PHP和Perl的代碼。mod_python比使用CGI或FastCGI更高效,因?yàn)樗恍枰獮槊恳粋€請求加載Python的解釋器。對mod_rails和mod_rack模塊來說也是一樣,這些模塊使得Apache可以運(yùn)行Ruby on Rails。這些進(jìn)程在Apache的進(jìn)程中運(yùn)行的更快一些。
所以,如果你的網(wǎng)站主要是用Python或Ruby開發(fā)的,你最好使用Apache,因?yàn)锳pache不需要使用CGI。對于PHP來說,用誰就無所謂了,因?yàn)镹ginx也支持內(nèi)建的PHP了。
我們在這里給出了Nginx和Apache之間的一些差異,以及我們該如何去考慮使用其中的一個或者兩者都用,以及哪一個更加適合你的需求。另外,我們也討論了Apache2.4已經(jīng)把Nginx在線程和進(jìn)程管理方面的一些提升加入到了Apache的服務(wù)器中。所以,你可以為你的需求找到最好的解決方案的。
原文地址:https://anturis.com/blog/nginx-vs-apache/
哈爾濱品用軟件有限公司致力于為哈爾濱的中小企業(yè)制作大氣、美觀的優(yōu)秀網(wǎng)站,并且能夠搭建符合百度排名規(guī)范的網(wǎng)站基底,使您的網(wǎng)站無需額外費(fèi)用,即可穩(wěn)步提升排名至首頁。歡迎體驗(yàn)最佳的哈爾濱網(wǎng)站建設(shè)。
