Nginx-詳解其原理

Nginx進程模型分析

在介紹Nginx的進程模型之前我們先來給大家解釋下一些常見的名詞,這能輔助我們更好的了解Nginx的進程模型未妹。作為Web服務器,設計的初衷就是為了能夠處理更多的客戶端的請求,一般來說棺克,完成并行處理請求工作有三種方式可以選擇唉侄,多進程咒吐、多線程、異步方式属划。

多進程方式

服務器每接收到一個客戶端請求恬叹,就會由主進程生成一個子進程出來和該請求建立連接進行交互,直到連接斷開以后子進程也就結束了
??優(yōu)點在于各個子進程之間相互獨立同眯,各個客戶端請求之間相互不受干擾绽昼。
??缺點是生成一個子進程需要進行內存復制、在資源和時間上會產生一定的額外開銷须蜗。如果請求比較多的時候硅确,會對系統(tǒng)資源造成一定的壓力

image.png

多線程方式

多線程方式和多進程方式很相似目溉,服務器每接收到一個客戶端請求時,會產生一個線程與該客戶端進行交互菱农。而產生一個線程的開銷比進程小很多缭付,所以多線程的方式在一定程度上減輕了web服務器對系統(tǒng)資源的要求。

缺點是多線程之間存在內存共享循未、彼此間存在相互影響的情況

image.png

異步方式

異步方式和前面說的兩種方式完全不一樣陷猫,關于異步這塊,還有幾個概念同步的妖、異步绣檬; 阻塞、非阻塞羔味,在這里一起做一個講解
??關于同步和異步河咽,我們很好理解。同步機制是指發(fā)送方發(fā)送請求后赋元,需要等待接收方返回響應后忘蟹,才能發(fā)送下一個請求,而異步機制搁凸,發(fā)送方發(fā)送請求后媚值,不等待接收方響應這個請求,就繼續(xù)發(fā)送下個請求护糖。

image.png

image.png

阻塞和非阻塞褥芒,主要指socket讀寫數據的阻塞和非阻塞方式。Socket的本質其實也是IO操作嫡良。每一個TCP Socket的內核中都有一個發(fā)送緩沖區(qū)和接收緩沖區(qū)锰扶。對與阻塞模式來說,如果接收緩沖區(qū)為空寝受,那么socket的read方法的線程就會阻塞坷牛,直到有數據進入接收緩沖區(qū)。而對于寫數據到socket中而言很澄,如果待發(fā)送的數據長度大于發(fā)送緩沖區(qū)的空余長度京闰,那么write方法會進入阻塞。
image.png

image.png

乍一看這四個概念的解釋會瞬間感到頭大甩苛,也經常講同步異步等同于阻塞非阻塞蹂楣,其實,區(qū)分他們非常簡單讯蒲。

同步異步與阻塞非阻塞的主要區(qū)別是針對對象不同痊土。

同步異步是針對調用者來說的,調用者發(fā)起一個請求后墨林,一直干等被調用者的反饋就是同步施戴,不必等去做別的事就是異步反浓。

阻塞非阻塞是針對被調用者來說的,被調用者收到一個請求后赞哗,做完請求任務后才給出反饋就是阻塞雷则,收到請求直接給出反饋再去做任務就是非阻塞。

而對于非阻塞模式來說肪笋,通過事件觸發(fā)的方式來達到目的月劈。我們可以認為NIO底層中存在一個I/O調度線程,它不斷的掃描每個Socket的緩沖區(qū)藤乙,當發(fā)現寫入緩沖區(qū)為空的時候猜揪,它會產生一個Socket可寫事件,此時程序就可以把數據寫入到Socket中坛梁。如果一次寫不完而姐,就等待下一次的可寫事件通知;反之划咐,當發(fā)現緩沖區(qū)里有數據的時候拴念,它會產生一個Socket可讀事件,程序收到這個通知事件就可以從Socket讀取數據了褐缠。
??那么基于這些概念又引除了四個概念:** 同步阻塞政鼠、同步非阻塞、異步阻塞队魏、異步非阻塞**

同步阻塞:發(fā)送方向接收方發(fā)送請求后公般,一直等待接收方響應;接收方在處理請求時進行的IO操作如果不能馬上得到結果胡桨,就一直等待結果返回才響應發(fā)送方官帘。期間一直處于阻塞狀態(tài);

image.png

同步非阻塞:發(fā)送方向接收方發(fā)送請求后昧谊,一直等待響應刽虹,接收方在進行IO操作的時候,可以不需要等待直接去做其他事揽浙,而因為還沒有獲得結果,發(fā)送方仍然處于等待狀態(tài)意敛。接收方獲得io的操作完成后馅巷,把結果響應給發(fā)送方,接收方才進入下一次請求過程
image.png

異步阻塞:發(fā)送方向接收方發(fā)送請求后草姻,不用等待響應钓猬,可以接著進行其他操作。接收方處理請求時進行的IO操作如果不能立刻獲得結果撩独,就一直等待返回結果后向發(fā)送方響應
image.png

異步非阻塞:發(fā)送方發(fā)送請求后敞曹,不用等待響應账月,可以繼續(xù)做其他事情。接收方處理請求時進行的IO操作如果不能馬上得到結果澳迫,也不等待局齿,而是去做其他事情。當io操作完成后橄登,把結果通知給接收方抓歼,接收方再響應給發(fā)送方
image.png

Nginx服務器的請求處理過程

Nginx結合了多進程機制和異步機制對外提供服務
??Nginx服務啟動后,會產生一個主進程和多個工作進程拢锹。

master進程主要用來管理worker進程谣妻,包含:接收來自外界的信號,向各worker進程發(fā)送信號卒稳,監(jiān)控worker進程的運行狀態(tài)蹋半,當worker進程退出后(異常情況下),會自動重新啟動新的worker進程
??而基本的網絡事件充坑,則是放在worker進程中來處理了减江。多個worker進程之間是對等的,他們同等競爭來自客戶端的請求匪傍,各進程互相之間是獨立的您市。一個請求,只可能在一個worker進程中處理役衡,一個worker進程茵休,不可能處理其它進程的求,worker進程的個數是可以設置的手蝎,一般我們會設置與機器cpu核數一致

Master進程的作用是榕莺?
讀取并驗證配置文件nginx.conf;管理worker進程棵介;
Worker進程的作用是钉鸯?
每一個Worker進程都維護一個線程(避免線程切換),處理連接和請求邮辽;注意Worker進程的個數由配置文件決定唠雕,一般和CPU個數相關(有利于進程切換),配置幾個就有幾個Worker進程吨述。

image.png

熱部署

master來管理worker進程岩睁,所以我們只需要與master進程通信就行了。master進程會接收來自外界發(fā)來的信號揣云,再根據信號做不同的事情,比如我們前面常用的

./sbin/nginx -c conf/nginx.conf -s reload 

執(zhí)行這個命令時捕儒,master收到這個信號以后先啟動一個新的Nginx進程,而新的Nginx進程在解析到reload參數后,就知道是要控制Nginx來重新加載配置文件刘莹,它會向master進程發(fā)送信號阎毅,然后master會重新加載配置文件,在啟動新的worker進程点弯,并向所有老的worker進程發(fā)送信號扇调,告訴他們可以退休了,新的worker啟動之后就可以以新的配置文件接收新的請求了 – 熱部署的原理


image.png

worker進程是如何處理請求蒲拉?

我們基本上知道了在操作nginx時肃拜,nginx內部所做的事情,那么worker進程是如何處理請求的呢雌团? 在Nginx中燃领,所有的worker進程都是平等的,每個進程處理每個請求的機會是一樣的锦援。當我們提供80端口的http服務時猛蔽,一個連接請求過來,每個進程都可能處理這個連接灵寺。
??worker進程是從master進程fork過來的曼库,而在master進程中,會先建立好需要listen的socket略板,然后fork出多個worker進程毁枯,當有新連接請求過來時work進程可以去處理,為了避免驚群效應叮称,worker進程在處理請求之前先要去搶占accept_mutex种玛,也就是互斥鎖,當獲得鎖成功以后瓤檐,就可以去解析處理這個請求赂韵。請求處理完以后再返回給客戶端。


image.png

image.png

進程模型的處理方式帶來的一些好處就是:進程之間是獨立的挠蛉,也就是一個worker進程出現異常退出祭示,其他worker進程是不會受到影響的;此外谴古,獨立進程也會避免一些不需要的鎖操作质涛,這樣子會提高處理效率,并且開發(fā)調試也更容易掰担。

worker進程會競爭監(jiān)聽客戶端的連接請求:這種方式可能會帶來一個問題汇陆,就是可能所有的請求都被一個worker進程給競爭獲取了,導致其他進程都比較空閑恩敌,而某一個進程會處于忙碌的狀態(tài)瞬测,這種狀態(tài)可能還會導致無法及時響應連接而丟棄discard掉本有能力處理的請求横媚。這種不公平的現象纠炮,是需要避免的月趟,尤其是在高可靠web服務器環(huán)境下。

針對這種現象恢口,Nginx采用了一個是否打開accept_mutex選項的值孝宗,ngx_accept_disabled標識控制一個worker進程是否需要去競爭獲取accept_mutex選項,進而獲取accept事件

ngx_accept_disabled值:nginx單進程的所有連接總數的八分之一耕肩,減去剩下的空閑連接數量因妇,得到的這個ngx_accept_disabled。
當ngx_accept_disabled大于0時猿诸,不會去嘗試獲取accept_mutex鎖婚被,并且將ngx_accept_disabled減1,于是梳虽,每次執(zhí)行到此處時址芯,都會去減1,直到小于0窜觉。不去獲取accept_mutex鎖谷炸,就是等于讓出獲取連接的機會,很顯然可以看出禀挫,當空閑連接越少時旬陡,ngx_accept_disable越大,于是讓出的機會就越多语婴,這樣其它進程獲取鎖的機會也就越大描孟。不去accept,自己的連接就控制下來了腻格,其它進程的連接池就會得到利用画拾,這樣,nginx就控制了多進程間連接的平衡了菜职。

好了~本文先介紹到這里青抛,有問題的歡迎留言交流 ~

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市酬核,隨后出現的幾起案子蜜另,更是在濱河造成了極大的恐慌,老刑警劉巖嫡意,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件举瑰,死亡現場離奇詭異,居然都是意外死亡蔬螟,警方通過查閱死者的電腦和手機此迅,發(fā)現死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人耸序,你說我怎么就攤上這事忍些。” “怎么了坎怪?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵罢坝,是天一觀的道長。 經常有香客問我搅窿,道長嘁酿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任男应,我火速辦了婚禮闹司,結果婚禮上,老公的妹妹穿的比我還像新娘沐飘。我一直安慰自己开仰,他們只是感情好,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布薪铜。 她就那樣靜靜地躺著众弓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪隔箍。 梳的紋絲不亂的頭發(fā)上谓娃,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天,我揣著相機與錄音蜒滩,去河邊找鬼滨达。 笑死,一個胖子當著我的面吹牛俯艰,可吹牛的內容都是我干的捡遍。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼竹握,長吁一口氣:“原來是場噩夢啊……” “哼画株!你這毒婦竟也來了?” 一聲冷哼從身側響起啦辐,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤谓传,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后芹关,有當地人在樹林里發(fā)現了一具尸體续挟,經...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年侥衬,在試婚紗的時候發(fā)現自己被綠了诗祸。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片跑芳。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖直颅,靈堂內的尸體忽然破棺而出聋亡,到底是詐尸還是另有隱情,我是刑警寧澤际乘,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站漂佩,受9級特大地震影響脖含,放射性物質發(fā)生泄漏。R本人自食惡果不足惜投蝉,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一养葵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瘩缆,春花似錦关拒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至熟尉,卻和暖如春归露,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背斤儿。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工剧包, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人往果。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓疆液,卻偏偏與公主長得像,于是被迫代替她去往敵國和親陕贮。 傳聞我的和親對象是個殘疾皇子堕油,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353