nginx的原理你必須知道的一些事。

nginx在啓動後,會有一個master進程和多個worker進程。master進程主要用來管理worker進程,包含:接收來自外界的信號,向各 個worker進程發送信號,監控worker進程的運行狀態,當worker進程退出後(異常情況下),會自動重新啓動新的worker進程。基本的網 絡事件,則是放在worker進程中來處理了。多個worker進程之間是對等的,他們同等競爭來自客戶端的請求,各進程互相之間是獨立的。一個請求,只 可能在一個worker進程中處理,一個worker進程,不可能處理其它進程的請求。worker進程的個數是可以設置的,一般我們會設置與機器cpu 核數一致。

worker進程是如何處理我們的http請求的?

master(master進程會先建立好需要listen的socket)--------fork生成子進程workers,繼承 socket(此時workers子進程們都繼承了父進程master的所有屬性,當然也包括已經建立好的socket,當然不是同一個socket,只 是每個進程的這個socket會監控在同一個ip地址與端口,這個在網絡協議裏面是允許的)------當一個連接進入,產生驚羣現象(驚羣現象:指一個fd的事件被觸發後,等候這個fd的所有線程/進程都被喚醒。雖然都被喚醒,但是隻有一個會去響應。)。

Nginx對驚羣現象的處理共享鎖

nginx提供了一個accept_mutex這個東西,從名字上,我們可以看這是一個加在accept上的一把共享鎖。有了這把鎖之後,同一時刻,就只會有一個進程在accpet連接,這樣就不會有驚羣問題了。accept_mutex是一個可控選項,我們可以顯示地關掉,默認是打開的。

worker進程工作

當一個worker進程在accept這個連接之後,就開始讀取請求,解析請求,處理請求,產生數據後,再返回給客戶端,最後才斷開連接,這樣一個完整的請求就是這樣的了。我們可以看到,一個請求,完全由worker進程來處理,而且只在一個worker進程中處理。

採用這種方式的好處:

1)節省鎖帶來的開銷。對於每個worker進程來說,獨立的進程,不需要加鎖,所以省掉了鎖帶來的開銷,同時在編程以及問題查上時,也會方便很多

2)獨立進程,減少風險。採用獨立的進程,可以讓互相之間不會影響,一個進程退出後,其它進程還在工作,服務不 會中斷, master進程則很快重新啓動新的worker進程。當然,worker進程的異常退出,肯定是程序有bug了,異常退出,會導致當前worker上的 所有請求失敗,不過不會影響到所有請求,所以降低了風險。

Nginx的事件處理機制,採用異步非阻塞事件處理機制,一個worker進程只有一個主線程,通過異步非阻塞的事件處理機制,實現了循環處理多個準備好的事件,從而實現輕量級和高併發。

異步非阻塞事件處理機制:

同步和異步的概念,這兩個概念與消息的通知機制有關.同步的情況下,是由處理消息者自己去等待消息是否被觸發,而異步的情況下是由觸發機制來通知處理消息者。

阻塞和非阻塞,這兩個概念與程序等待消息(無所謂同步或者異步)時的狀態有關.

當讀寫事件沒有準備好時,就放入epoll裏面。如果有事件準備好了,那麼就去處理;如果事件返回的是EAGAIN,那麼繼續將其放入epoll裏 面。從而,只要有事件準備好了,我們就去處理,只有當所有時間都沒有準備好時,纔在epoll裏面等着。這樣,我們就可以併發處理大量的併發了,當然,這 裏的併發請求,是指未處理完的請求,線程只有一個,所以同時能處理的請求當然只有一個了,只是在請求間進行不斷地切換而已,切換也是因爲異步事件未準備 好,而主動讓出的。這裏的切換是沒有任何代價,你可以理解爲循環處理多個準備好的事件。

與多線程相比,這種事件處理方式是有很大的優勢的,不需要創建線程,每個請求佔用的內存也很少,沒有上下文切換,事件處理非常的輕量級。併發數再多也不會導致無謂的資源浪費(上下文切換)。更多的併發數,只是會佔用更多的內存而已.

之前我們提到nginx的負載均衡功能,那麼和LVS的負載均衡有什麼區別呢?

負載均衡分爲:

L4 switch(四層交換),即在OSI第4層工作,就是TCP層啦。此種Load Balance不理解應用協議(如HTTP/FTP/MySQL等等)。例子:LVS,F5

L7 switch(七層交換),OSI的最高層,應用層。此時,該Load Balancer能理解應用協議。例子:haproxy,MySQL Proxy

很多Load Balancer(例如F5)既可以做四層交換,也可以做七層交換。

LVS 工作在網絡4層僅做請求分發之用沒有流量,可配置性低,幾乎可對所有應用做負載均衡,對網絡依賴大,沒有健康檢查機制。

nginx的7層(應用層),所以它可以針對http應用本身來做分流策略,比如針對域名、目錄結構等,對網絡依賴小,可檢測服務器內部錯誤。
 

nginx可以根據URL進行負載均衡的請求轉發,而LVS只能根據ip:port進行請求轉發

一般情況下,LVS會被放在最前端做負載均衡,nginx可作爲lvs的節點服務器。

前面我們也提到過nginx實現郵件代理服務器的功能,一般使用nginx做郵件代理服務器的場景不多。

很不幸,nginx最早也是被當作郵件代理服務器來開發的。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章