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