Nginx是一款輕量級(jí)的Web服務(wù)器/反向代理服務(wù)器及電子郵件(IMAP/POP3)代理服務(wù)器,其特點(diǎn)是占有內(nèi)存少、并發(fā)能力強(qiáng),因它的穩(wěn)定性、豐富的功能集、示例配置文件和低系統(tǒng)資源的消耗而聞名,也由此受到了很多大廠的青睞。
那么Nginx是如何實(shí)現(xiàn)的高并發(fā)的呢?下面將為大家分享一下Nginx架構(gòu)設(shè)計(jì),探究一下Nginx備受青睞的秘訣在哪里。
Nginx其實(shí)有兩種進(jìn)程結(jié)構(gòu),一種是單進(jìn)程結(jié)構(gòu),一種是多進(jìn)程結(jié)構(gòu)。在我們實(shí)際生產(chǎn)環(huán)境中,由于需要保持nginx的健壯性,因此多進(jìn)程結(jié)構(gòu)較為實(shí)用且常見(jiàn)。
為什么是多進(jìn)程結(jié)構(gòu),而不是多線程結(jié)構(gòu)?
首先我們來(lái)看一下多進(jìn)程與多線程的對(duì)比:
Nginx最核心的一個(gè)目的是要保持高可用性、高可靠性,在采用多進(jìn)程結(jié)構(gòu)時(shí),由于和進(jìn)程間不會(huì)相互影響,單個(gè)進(jìn)程出現(xiàn)異常并不會(huì)導(dǎo)致整個(gè)Nginx服務(wù)掛掉。同時(shí),多個(gè)worker進(jìn)程可以分別占用不同的CPU核心來(lái)工作,提高了Nginx處理請(qǐng)求的速度。另外,采用多進(jìn)程模型還可以通過(guò)進(jìn)程間通信來(lái)實(shí)現(xiàn)負(fù)載均衡,即一個(gè)請(qǐng)求到來(lái)時(shí)更容易被分配到負(fù)載較輕的worker工作進(jìn)程中處理,這也同樣提高了Nginx的請(qǐng)求處理能力。
如上圖所示,Nginx在啟動(dòng)后,會(huì)有一個(gè)master進(jìn)程和多個(gè)worker進(jìn)程。
master進(jìn)程主要用來(lái)做worker進(jìn)程的管理,包含:接收來(lái)自外界的信號(hào)、向各worker進(jìn)程發(fā)送信號(hào)、監(jiān)控worker進(jìn)程的運(yùn)行狀態(tài)、Nginx配置文件重新載入等。worker進(jìn)程,才是處理真正請(qǐng)求的工作進(jìn)程。
cache(緩存)是在多個(gè)worker進(jìn)程間共享的,而且緩存不僅要被worker進(jìn)程使用,還要被cachemanager 和cacheloader進(jìn)程使用。cachemanager 和cacheloader 也是為反向代理時(shí),后端發(fā)來(lái)的動(dòng)態(tài)請(qǐng)求做緩存所使用的,cacheloader 只是用來(lái)做緩存的載入、cachemanager 用來(lái)做緩存的管理。實(shí)際上每個(gè)請(qǐng)求處理時(shí),使用到緩存還是由worker進(jìn)程來(lái)進(jìn)行的。
這些進(jìn)程間的通訊,都是使用共享內(nèi)存來(lái)解決的。可以看到cachemanager 和cacheloader各有一個(gè)進(jìn)程,master進(jìn)程因?yàn)槭歉高M(jìn)程,所以肯定只有一個(gè)。那么worker進(jìn)程為什么會(huì)有很多呢?這是因?yàn)镹ginx采用了事件驅(qū)動(dòng)引擎以后,他希望每一個(gè)worker進(jìn)程從頭到尾占有一顆CPU,所以往往不止要把worker進(jìn)程的數(shù)量配置與我們服務(wù)器上的CPU核數(shù)一致以外,還需要把每一個(gè)worker進(jìn)程與某一顆CPU核綁定在一起,這樣可以更好的使用每顆CPU核上面的CPU緩存來(lái)減少緩存失效的命中率。
基本概念:
異步、同步
同步和異步,這兩個(gè)概念是從客戶端與服務(wù)器之間的通信交互方式得來(lái)的。
同步,指客戶端向服務(wù)器發(fā)送一個(gè)請(qǐng)求后、必須接收到服務(wù)器對(duì)此請(qǐng)求的響應(yīng)后,才會(huì)再向服務(wù)器發(fā)送下一個(gè)請(qǐng)求。
異步,指客戶端向服務(wù)器發(fā)送一個(gè)請(qǐng)求后,并不等待服務(wù)器對(duì)此請(qǐng)求的響應(yīng),便發(fā)送了下一個(gè)請(qǐng)求。
阻塞、非阻塞
阻塞和非阻塞,這兩個(gè)概念是從服務(wù)器內(nèi)部處理請(qǐng)求的方式來(lái)說(shuō)的。
阻塞,指服務(wù)器接收到請(qǐng)求后,如果遇到IO阻塞,當(dāng)前線程會(huì)被掛起,知道IO完成后喚醒當(dāng)前線程,當(dāng)前線程期間不會(huì)去處理其他事情。
非阻塞,指服務(wù)器接收到請(qǐng)求后,如果遇到IO阻塞,當(dāng)前線程不會(huì)掛起,而是會(huì)立即返回去執(zhí)行下一個(gè)調(diào)用。
同步與異步,重點(diǎn)在于消息通知的方式;阻塞與非阻塞,重點(diǎn)在于等消息時(shí)候的行為。
所以,就有了下面4種組合方式:
同步阻塞:小明收到信息后,啥都不干,等快遞;
同步非阻塞:小明收到信息后,邊刷微博,邊等著取快遞;
異步阻塞:小明收到信息后,啥都不干,一直等著快遞員通知他取快遞;
異步非阻塞:小明收到信息后,邊刷著微博,邊等快遞員通知他取快遞。
Nginx之所以可以支持高并發(fā),就是因?yàn)镹ginx用的是上述所講的異步非阻塞的機(jī)制,而Nginx是靠事件驅(qū)動(dòng)模型來(lái)實(shí)現(xiàn)這種機(jī)制的。
在Nginx的事件驅(qū)動(dòng)模型下,客戶端發(fā)起的所有請(qǐng)求在服務(wù)端都會(huì)被標(biāo)記為一個(gè)事件,Nginx會(huì)把這些事件收集到“事件收集器”里,然后再把這些事件交給內(nèi)核去處理。
Nginx的事件驅(qū)動(dòng)模型
Nginx的事件驅(qū)動(dòng)模型,支持select、poll、epoll、rtsig、kqueue、/dev/poll、eventport等,最常用的是前三種。
Select模型:首先會(huì)創(chuàng)建所關(guān)注事件的描述符集合。會(huì)分別創(chuàng)建讀(Read)事件、寫(Write)事件、異常發(fā)生(Exception)事件三類描述符集合來(lái)收集三類描述符。然后調(diào)用底層提供的select()函數(shù),等待事件發(fā)生。最后輪詢所有事件描述符集合中的每一個(gè)描述符,檢查是否有相應(yīng)的事件發(fā)生,然后處理事件。
Poll模型:其與select的基本實(shí)現(xiàn)方式相同,只不過(guò)創(chuàng)建關(guān)注的描述符集合時(shí),不分成三個(gè)集合,而是一個(gè)集合包括所有描述符。
Epoll模型:當(dāng)描述符比較多時(shí),遍歷描述符集合、然后查找每個(gè)描述符是否有相應(yīng)事件發(fā)生這一過(guò)程會(huì)效率較低。epoll選擇將描述符列表的管理交給內(nèi)核復(fù)制,一旦有事件發(fā)生,內(nèi)核會(huì)將有事件發(fā)生的描述符列表通知給進(jìn)程,這樣避免了應(yīng)用程序輪詢整個(gè)描述符列表。epoll會(huì)通過(guò)相關(guān)調(diào)用,通知內(nèi)核創(chuàng)建一個(gè)N個(gè)描述符的事件列表,然后給這些描述符設(shè)置所關(guān)注的事件,并把他添加到內(nèi)核的事件列表中,在編碼過(guò)程中也可以通過(guò)相關(guān)調(diào)用對(duì)事件列表中的描述符進(jìn)行動(dòng)態(tài)地刪除和修改。
Nginx是如何實(shí)現(xiàn)高并發(fā)的?
如果一個(gè)server采用一個(gè)進(jìn)程負(fù)責(zé)一個(gè)request的方式,那么進(jìn)程數(shù)就是并發(fā)數(shù)。正常情況下,會(huì)有很多進(jìn)程一直在等待中。而nginx采用一個(gè)master進(jìn)程,多個(gè)woker進(jìn)程的模式。master進(jìn)程主要負(fù)責(zé)收集、分發(fā)請(qǐng)求。每當(dāng)一個(gè)請(qǐng)求過(guò)來(lái)時(shí),master就拉起一個(gè)worker進(jìn)程負(fù)責(zé)處理這個(gè)請(qǐng)求。同時(shí)master進(jìn)程也負(fù)責(zé)監(jiān)控woker的狀態(tài),保證高可靠性。woker進(jìn)程一般設(shè)置為跟cpu核心數(shù)一致。nginx的woker進(jìn)程在同一時(shí)間可以處理的請(qǐng)求數(shù)只受內(nèi)存限制,可以處理多個(gè)請(qǐng)求。Nginx的異步非阻塞工作方式正把當(dāng)中的等待時(shí)間利用起來(lái)了。在需要等待的時(shí)候,這些進(jìn)程就空閑出來(lái)待命了,因此表現(xiàn)為少數(shù)幾個(gè)進(jìn)程就解決了大量的并發(fā)問(wèn)題。每進(jìn)來(lái)一個(gè)request,會(huì)有一個(gè)worker進(jìn)程去處理。但不是全程的處理,處理到什么程度呢?處理到可能發(fā)生阻塞的地方,比如向上游(后端)服務(wù)器轉(zhuǎn)發(fā)request,并等待請(qǐng)求返回。那么,這個(gè)處理的worker很聰明,他會(huì)在發(fā)送完請(qǐng)求后,注冊(cè)一個(gè)事件:“如果upstream返回了,告訴我一聲,我再接著干”。于是他就休息去了。此時(shí),如果再有request進(jìn)來(lái),他就可以很快再按這種方式處理。而一旦上游服務(wù)器返回了,就會(huì)觸發(fā)這個(gè)事件,worker才會(huì)來(lái)接手,這個(gè)request才會(huì)接著往下走。
因此,多進(jìn)程結(jié)構(gòu)、異步非阻塞的處理機(jī)制和采用事件驅(qū)動(dòng)模型(epoll)就是Nginx實(shí)現(xiàn)高并發(fā)的秘密所在。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/129976.html
摘要:使用了多路復(fù)用技術(shù)的,就成了并發(fā)事件驅(qū)動(dòng)的服務(wù)器。進(jìn)程主要負(fù)責(zé)收集分發(fā)請(qǐng)求。同時(shí)進(jìn)程也負(fù)責(zé)監(jiān)控的狀態(tài),保證高可靠性進(jìn)程一般設(shè)置為跟核心數(shù)一致。所以才使得支持更高的并發(fā)。配置調(diào)優(yōu)調(diào)整指要生成的數(shù)量最佳實(shí)踐是每個(gè)運(yùn)行個(gè)工作進(jìn)程。 Nginx 是如何實(shí)現(xiàn)高并發(fā)的? Nginx 采用的是多進(jìn)程(單線程) & 多路IO復(fù)用模型。使用了 I/O 多路復(fù)用技術(shù)的 Nginx,就成了并發(fā)事件驅(qū)動(dòng)的服務(wù)...
摘要:一閱前熱身為了更加形象的說(shuō)明同步異步阻塞非阻塞,我們以小明去買奶茶為例。等奶茶做好了,店員喊一聲小明,奶茶好了,然后小明去取奶茶。將響應(yīng)結(jié)果發(fā)給相應(yīng)的連接請(qǐng)求處理完成因?yàn)榛冢悦總€(gè)可以處理無(wú)數(shù)個(gè)連接請(qǐng)求。如此,就輕松的處理了高并發(fā)。 一、閱前熱身 為了更加形象的說(shuō)明同步異步、阻塞非阻塞,我們以小明去買奶茶為例。 1、同步與異步 ①同步與異步的理解 同步與異步的重點(diǎn)在消息通知的方式上...
摘要:一閱前熱身為了更加形象的說(shuō)明同步異步阻塞非阻塞,我們以小明去買奶茶為例。等奶茶做好了,店員喊一聲小明,奶茶好了,然后小明去取奶茶。將響應(yīng)結(jié)果發(fā)給相應(yīng)的連接請(qǐng)求處理完成因?yàn)榛冢悦總€(gè)可以處理無(wú)數(shù)個(gè)連接請(qǐng)求。如此,就輕松的處理了高并發(fā)。 一、閱前熱身 為了更加形象的說(shuō)明同步異步、阻塞非阻塞,我們以小明去買奶茶為例。 1、同步與異步 ①同步與異步的理解 同步與異步的重點(diǎn)在消息通知的方式上...
摘要:表示的是兩個(gè),當(dāng)其中任意一個(gè)計(jì)算完并發(fā)編程之是線程安全并且高效的,在并發(fā)編程中經(jīng)常可見(jiàn)它的使用,在開(kāi)始分析它的高并發(fā)實(shí)現(xiàn)機(jī)制前,先講講廢話,看看它是如何被引入的。電商秒殺和搶購(gòu),是兩個(gè)比較典型的互聯(lián)網(wǎng)高并發(fā)場(chǎng)景。 干貨:深度剖析分布式搜索引擎設(shè)計(jì) 分布式,高可用,和機(jī)器學(xué)習(xí)一樣,最近幾年被提及得最多的名詞,聽(tīng)名字多牛逼,來(lái),我們一步一步來(lái)?yè)羝魄皟蓚€(gè)名詞,今天我們首先來(lái)說(shuō)說(shuō)分布式。 探究...
摘要:表示的是兩個(gè),當(dāng)其中任意一個(gè)計(jì)算完并發(fā)編程之是線程安全并且高效的,在并發(fā)編程中經(jīng)常可見(jiàn)它的使用,在開(kāi)始分析它的高并發(fā)實(shí)現(xiàn)機(jī)制前,先講講廢話,看看它是如何被引入的。電商秒殺和搶購(gòu),是兩個(gè)比較典型的互聯(lián)網(wǎng)高并發(fā)場(chǎng)景。 干貨:深度剖析分布式搜索引擎設(shè)計(jì) 分布式,高可用,和機(jī)器學(xué)習(xí)一樣,最近幾年被提及得最多的名詞,聽(tīng)名字多牛逼,來(lái),我們一步一步來(lái)?yè)羝魄皟蓚€(gè)名詞,今天我們首先來(lái)說(shuō)說(shuō)分布式。 探究...
閱讀 1346·2023-01-11 13:20
閱讀 1684·2023-01-11 13:20
閱讀 1132·2023-01-11 13:20
閱讀 1858·2023-01-11 13:20
閱讀 4100·2023-01-11 13:20
閱讀 2704·2023-01-11 13:20
閱讀 1385·2023-01-11 13:20
閱讀 3597·2023-01-11 13:20