什么是Nginx代理代理服務(wù)器,它和Apache相比又有什么區(qū)別呢?你又該如何選擇使用呢,用其中一個(gè)還是兩者都用?我們將會(huì)在這里探索一下這些問(wèn)題的答案。

  Apache服務(wù)器從1995年就開始使用了。相比其他產(chǎn)品,Apache服務(wù)器是使用最多的,其次是微軟的IIS服務(wù)器。

  由于開源的Apache服務(wù)器已經(jīng)被使用多年,并且有眾多的用戶,人們開發(fā)出了很多的模塊來(lái)擴(kuò)展它的功能,其中的大多數(shù)模塊也是開源的。舉例來(lái)說(shuō),一個(gè)比較常見(jiàn)的配置是使用Apache來(lái)為靜態(tài)頁(yè)面提供服務(wù),并使用mod_jk模塊來(lái)運(yùn)行Tomcat上的Java和JSP代碼,以便使程序具有交互功能。另一個(gè)例子是使用mod_php模塊來(lái)執(zhí)行php代碼,而不用去使用cgi。

  但是,Apache在高負(fù)載的情況下表現(xiàn)的差強(qiáng)人意,原因是它需要去運(yùn)行新的進(jìn)程,因此要消耗更多的內(nèi)存。同時(shí),他還要產(chǎn)生新的線程來(lái)與其他的線程競(jìng)爭(zhēng)內(nèi)存和CPU。當(dāng)進(jìn)程的流量達(dá)到了管理員設(shè)置的上限時(shí),Apache會(huì)拒絕新的連接。

  Nginx 是一個(gè)開源的服務(wù)器,用來(lái)解決一些Apache在性能和擴(kuò)展性方面的問(wèn)題的。Nginx是開源并且免費(fèi)的,但是如果你購(gòu)買了它的Nginx Plus版本的話是可以享受到服務(wù)支持的。

  Nginx 聲稱它的服務(wù)器是用來(lái)解決C10K問(wèn)題(出自Daniel Kegel發(fā)表的一篇關(guān)于如何使一個(gè)服務(wù)器處理10000個(gè)連接——假設(shè)的操作系統(tǒng)的上限的論文)的。在他的論文中,他引用了另一篇由Dean Gaudet寫的論文,其中寫到“你們?yōu)槭裁床皇褂靡粋€(gè)像Zeus那樣的選擇/事件(select/event)為基礎(chǔ)的模型呢?很明顯那是最快的”。

  Nginx 確實(shí)是以事件為基礎(chǔ)的(event-based)。他們把他們的架構(gòu)稱為“事件驅(qū)動(dòng)且異步”(event-driven and asynchronous)。Apache 依賴于進(jìn)程和線程。那么,區(qū)別是什么呢?

 Apache是如何工作的,為什么會(huì)有極限

  Apache通過(guò)創(chuàng)建進(jìn)程和線程來(lái)處理其他的連接。管理員可以通過(guò)設(shè)置來(lái)控制服務(wù)器所能允許的最大進(jìn)程數(shù)量。這個(gè)配置因機(jī)器的可用內(nèi)存而異。過(guò)多的進(jìn)程會(huì)耗盡內(nèi)存從而使得機(jī)器使用磁盤上的交換內(nèi)存,這嚴(yán)重的降低了性能。而且,當(dāng)達(dá)到進(jìn)程的上限之后,Apache會(huì)拒絕新的連接。

  Apache可以通過(guò)設(shè)置來(lái)運(yùn)行在pre-forked 模式或worker multi-process 模式(MPM)。當(dāng)其他的用戶連接時(shí),兩種方式都會(huì)創(chuàng)建新的進(jìn)程。區(qū)別在于,pre-forked模式為每一個(gè)進(jìn)程創(chuàng)建一個(gè)線程,用來(lái)處理一個(gè)用戶的請(qǐng)求。worker模式也創(chuàng)建新的進(jìn)程,但是每一個(gè)進(jìn)程至少有一個(gè)線程,每一個(gè)線程用來(lái)處理單個(gè)用戶的單個(gè)請(qǐng)求。所以,一個(gè)worker mode 的進(jìn)程處理至少一個(gè)連接,而一個(gè)per-fork 模式的進(jìn)程只處理一個(gè)連接。

  相比于forked 模式,worker 模式使用更少的內(nèi)存,原因是進(jìn)程比線程消耗更多的內(nèi)存,線程只是運(yùn)行在進(jìn)程中的代碼。

  此外,worker模式不是線程安全的。這意味著如果你使用像mod_php這樣的非線程安全的模塊來(lái)服務(wù)php頁(yè)面時(shí),你需要使用pre-forked模式,因此要消耗更多的內(nèi)存。所以,當(dāng)選擇模塊和配置服務(wù)器時(shí),你必須要面對(duì)是線程還是進(jìn)程更優(yōu)的問(wèn)題以及一些約束的問(wèn)題。

  在調(diào)整Apache時(shí)的一個(gè)限制因素是內(nèi)存以及當(dāng)爭(zhēng)奪同一個(gè)CPU和內(nèi)存時(shí)潛在的線程死鎖問(wèn)題。如果一個(gè)線程停止了,用戶會(huì)一直處于等待頁(yè)面出現(xiàn)的狀態(tài),直到進(jìn)程將該線程回收,以便可以發(fā)回頁(yè)面。如果一個(gè)線程發(fā)生了死鎖,它不知道如何重啟,因此會(huì)一直處于卡住狀態(tài)。

 Nginx

  和Apache相比,Nginx的工作方式有很大不同,主要是在于它如何處理線程。

  Nginx并不會(huì)為每一個(gè)的web請(qǐng)求創(chuàng)建新的進(jìn)程,相反,管理員可以配置Nginx主進(jìn)程的工作進(jìn)程的數(shù)量(一個(gè)常見(jiàn)的做法是為每一個(gè)CPU配置一個(gè)工作進(jìn)程)。所有這些進(jìn)程都是單線程的。每一個(gè)工作進(jìn)程可以處理數(shù)千個(gè)并發(fā)的請(qǐng)求。它通過(guò)一個(gè)線程來(lái)異步的完成了這些工作,而沒(méi)有使用多線程的編程模型。

  Nginx還拆分了緩存加載器(cache loader)和緩存管理器(cache manager)進(jìn)程用來(lái)從磁盤中讀取數(shù)據(jù)并將其加載到緩存中,當(dāng)緩存直接讀取的時(shí)候緩存過(guò)期。

  Nginx有一系列的模塊組成,這些模塊在編譯的時(shí)候就被包含進(jìn)去了。這意味著,用戶下載源碼并選擇他們要編譯的模塊。這些模塊中包括連接后端應(yīng)用服務(wù)器,負(fù)載均衡,代理服務(wù)器以及其他。并沒(méi)有PHP的模塊,因?yàn)镹ginx可以自己編譯PHP代碼。

  這里有一張圖描述了Nginx的架構(gòu),該圖來(lái)自Andrew Alexeev的深入分析Nginx及其工作方式。

  從這個(gè)圖表中我們可以看出,Nginx使用FastCGI進(jìn)程來(lái)執(zhí)行Python,Ruby以及其他代碼,使用Memcached對(duì)象緩存系統(tǒng)。工作進(jìn)程為HTTP請(qǐng)求加載ht_core Nginx進(jìn)程。我們還可以看到,Nginx和Windows以及Linux內(nèi)核的功能緊密的集成在了一起,以便提升性能。這些內(nèi)核功能已經(jīng)經(jīng)過(guò)長(zhǎng)時(shí)間的改良,而Nginx正是利用了這一點(diǎn)。

  Nginx聲稱是事件驅(qū)動(dòng),異步且無(wú)阻塞的?!笆录?Event)”指的是一個(gè)用戶的連接?!爱惒?Asynchronous)”指的是它一次處理多個(gè)用戶連接的用戶交互?!盁o(wú)阻塞(Non-blocking)”指的是它不會(huì)由于CPU處于忙狀態(tài)而停止磁盤的I/O,在這種情況下,它會(huì)處理其他事件,直到I/O資源得到釋放。

 Nginx 與 Apache 2.4 MPM

  Apache 2.4包含多路處理事件模塊(MPM event module)。它能處理在異步方式下的連接類型,Niginx同樣也能做,但是在方式上是不一樣的。目的是在負(fù)載增長(zhǎng)的時(shí)候,壓縮對(duì)內(nèi)存的需求。

  在早期的版本中,Apache 2.4包含工作者(worker)和前復(fù)制叉(pre-forked)模式,除了我們之前提到那些,還包括已經(jīng)被添加的mpm_event_module(Apache MPM event module),它被用來(lái)解決為了?;疃却@個(gè)連接的線程問(wèn)題(等待是因?yàn)檫@個(gè)連接是用戶額外的請(qǐng)求)。MPM致力于一個(gè)線程能處理套接字(sockets)中監(jiān)聽(listening)和保活(keep-alive)這兩者的狀態(tài)。這個(gè)關(guān)于地址的內(nèi)存問(wèn)題與舊版本的Apache相關(guān),通過(guò)減少線程數(shù)量以及進(jìn)程的創(chuàng)建次數(shù)。正是這一點(diǎn),管理員可能要下載Apache的源代碼并且包括mem_event_module,還要編譯Apache,用以代替正在使用的二進(jìn)制發(fā)行版。

  Apache的MPM事件模型與Nginx的并不完全相同,這是因?yàn)楫?dāng)Apache接收到新的請(qǐng)求(請(qǐng)求的數(shù)量受到管理員所設(shè)置的限制)時(shí),它就會(huì)產(chǎn)生新的進(jìn)程。Nginx不會(huì)為每個(gè)用戶創(chuàng)建多個(gè)進(jìn)程。在Apache 4.2上做了如下改進(jìn):與Apache通常的工作者模式相比 ,這個(gè)版本里所創(chuàng)建的服務(wù)進(jìn)程將會(huì)生成更少的線程。這是因?yàn)橐粋€(gè)線程可以處理多個(gè)連接,而不是每個(gè)連接需要一個(gè)進(jìn)程為其提供服務(wù)。

  既使用Nginx,又使用Apache

  Apache是因?yàn)槠涔δ軓?qiáng)大而出名的,而Nginx是因?yàn)槠漤憫?yīng)速度快而著稱的。這就意味著Nginx在靜態(tài)內(nèi)容的服務(wù)上要相對(duì)快些,不過(guò),Apache可以使用模塊來(lái)運(yùn)行后臺(tái)應(yīng)用服務(wù)器,而且還可以運(yùn)行腳本語(yǔ)言。

  Apache和Nginx都可以用作代理服務(wù)器,不過(guò)通常我們會(huì)把Nginx用作代理服務(wù)器,而把Apache用作后臺(tái)服務(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是一個(gè)應(yīng)用,這是因?yàn)樗皇菆?zhí)行期間可以裝載的.dll或者.so,而是與Apache的模塊使用方法相同。Ngnix使用php-fpm(FastCGI進(jìn)程管理器)來(lái)處理php腳本,這就使得Nginx具有生成非靜態(tài)內(nèi)容的功能。

 什么時(shí)候更適合用Apache?

  Apache 具有內(nèi)建支持PHP,Python,Perl等語(yǔ)言的能力。例如,mod_perl和mod_php模塊可以用來(lái)在Apache的進(jìn)程中處理PHP和Perl的代碼。mod_python比使用CGI或FastCGI更高效,因?yàn)樗恍枰獮槊恳粋€(gè)請(qǐng)求加載Python的解釋器。對(duì)mod_rails和mod_rack模塊來(lái)說(shuō)也是一樣,這些模塊使得Apache可以運(yùn)行Ruby on Rails。這些進(jìn)程在Apache的進(jìn)程中運(yùn)行的更快一些。

  所以,如果你的網(wǎng)站主要是用Python或Ruby開發(fā)的,你最好使用Apache,因?yàn)锳pache不需要使用CGI。對(duì)于PHP來(lái)說(shuō),用誰(shuí)就無(wú)所謂了,因?yàn)镹ginx也支持內(nèi)建的PHP了。

  我們?cè)谶@里給出了Nginx和Apache之間的一些差異,以及我們?cè)撊绾稳タ紤]使用其中的一個(gè)或者兩者都用,以及哪一個(gè)更加適合你的需求。另外,我們也討論了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)站無(wú)需額外費(fèi)用,即可穩(wěn)步提升排名至首頁(yè)。歡迎體驗(yàn)最佳的哈爾濱網(wǎng)站建設(shè)