溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Nginx的事件處理模型怎么理解

發(fā)布時(shí)間:2021-12-10 16:07:55 來源:億速云 閱讀:220 作者:iii 欄目:系統(tǒng)運(yùn)維

本篇內(nèi)容介紹了“Nginx的事件處理模型怎么理解”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

 Nginx 的進(jìn)程模型

Nginx的事件處理模型怎么理解

Nginx 服務(wù)器,正常運(yùn)行過程中:

  1. 多進(jìn)程:一個(gè) Master 進(jìn)程、多個(gè) Worker 進(jìn)程

  2. Master 進(jìn)程:管理 Worker 進(jìn)程

  3. 對(duì)外接口:接收外部的操作(信號(hào))

  4. 對(duì)內(nèi)轉(zhuǎn)發(fā):根據(jù)外部的操作的不同,通過信號(hào)管理 Worker

  5. 監(jiān)控:監(jiān)控 worker 進(jìn)程的運(yùn)行狀態(tài),worker 進(jìn)程異常終止后,自動(dòng)重啟 worker 進(jìn)程

  6. Worker 進(jìn)程:所有 Worker 進(jìn)程都是平等的

  7. 實(shí)際處理:網(wǎng)絡(luò)請(qǐng)求,由 Worker 進(jìn)程處理;

  8. Worker 進(jìn)程數(shù)量:在 nginx.conf 中配置,一般設(shè)置為核心數(shù),充分利用 CPU 資源,同時(shí),避免進(jìn)程數(shù)量過多,避免進(jìn)程競爭 CPU 資源,增加上下文切換的損耗。

思考:

  1. 請(qǐng)求是連接到 Nginx,Master 進(jìn)程負(fù)責(zé)處理和轉(zhuǎn)發(fā)?

  2. 如何選定哪個(gè) Worker 進(jìn)程處理請(qǐng)求?請(qǐng)求的處理結(jié)果,是否還要經(jīng)過 Master 進(jìn)程?

Nginx的事件處理模型怎么理解

HTTP 連接建立和請(qǐng)求處理過程

  1. Nginx 啟動(dòng)時(shí),Master 進(jìn)程,加載配置文件

  2. Master 進(jìn)程,初始化監(jiān)聽的 socket

  3. Master 進(jìn)程,fork 出多個(gè) Worker 進(jìn)程

  4. Worker 進(jìn)程,競爭新的連接,獲勝方通過三次握手,建立 Socket 連接,并處理請(qǐng)求

Nginx 高性能、高并發(fā)

  1. Nginx 采用:多進(jìn)程 + 異步非阻塞方式(IO 多路復(fù)用 epoll)

  2. 請(qǐng)求的完整過程:

  3. 建立連接

  4. 讀取請(qǐng)求:解析請(qǐng)求

  5. 處理請(qǐng)求

  6. 響應(yīng)請(qǐng)求

  7. 請(qǐng)求的完整過程,對(duì)應(yīng)到底層,就是:讀寫 socket 事件

Nginx 的事件處理模型

request:Nginx 中 http 請(qǐng)求。

基本的 HTTP Web Server 工作模式:

  1. 接收請(qǐng)求:逐行讀取請(qǐng)求行和請(qǐng)求頭,判斷段有請(qǐng)求體后,讀取請(qǐng)求體

  2. 處理請(qǐng)求

  3. 返回響應(yīng):根據(jù)處理結(jié)果,生成相應(yīng)的 HTTP 請(qǐng)求(響應(yīng)行、響應(yīng)頭、響應(yīng)體)

Nginx 也是這個(gè)套路,整體流程一致。

Nginx的事件處理模型怎么理解

模塊化體系結(jié)構(gòu)

Nginx的事件處理模型怎么理解

nginx的模塊根據(jù)其功能基本上可以分為以下幾種類型:

  • event module: 搭建了獨(dú)立于操作系統(tǒng)的事件處理機(jī)制的框架,及提供了各具體事件的處理。包括ngx_events_module, ngx_event_core_module和ngx_epoll_module等。nginx具體使用何種事件處理模塊,這依賴于具體的操作系統(tǒng)和編譯選項(xiàng)。

  • phase handler: 此類型的模塊也被直接稱為handler模塊。主要負(fù)責(zé)處理客戶端請(qǐng)求并產(chǎn)生待響應(yīng)內(nèi)容,比如ngx_http_static_module模塊,負(fù)責(zé)客戶端的靜態(tài)頁面請(qǐng)求處理并將對(duì)應(yīng)的磁盤文件準(zhǔn)備為響應(yīng)內(nèi)容輸出。

  • output filter: 也稱為filter模塊,主要是負(fù)責(zé)對(duì)輸出的內(nèi)容進(jìn)行處理,可以對(duì)輸出進(jìn)行修改。例如,可以實(shí)現(xiàn)對(duì)輸出的所有html頁面增加預(yù)定義的footbar一類的工作,或者對(duì)輸出的圖片的URL進(jìn)行替換之類的工作。

  • upstream: upstream模塊實(shí)現(xiàn)反向代理的功能,將真正的請(qǐng)求轉(zhuǎn)發(fā)到后端服務(wù)器上,并從后端服務(wù)器上讀取響應(yīng),發(fā)回客戶端。upstream模塊是一種特殊的handler,只不過響應(yīng)內(nèi)容不是真正由自己產(chǎn)生的,而是從后端服務(wù)器上讀取的。

  • load-balancer: 負(fù)載均衡模塊,實(shí)現(xiàn)特定的算法,在眾多的后端服務(wù)器中,選擇一個(gè)服務(wù)器出來作為某個(gè)請(qǐng)求的轉(zhuǎn)發(fā)服務(wù)器。

常見問題剖析

Nginx vs. Apache

網(wǎng)絡(luò) IO 模型:

  1. nginx:IO 多路復(fù)用,epoll(freebsd 上是 kqueue )

  2. 高性能

  3. 高并發(fā)

  4. 占用系統(tǒng)資源少

  5. apache:阻塞 + 多進(jìn)程/多線程

  6. 更穩(wěn)定,bug 少

  7. 模塊更豐富

場景:

處理多個(gè)請(qǐng)求時(shí),可以采用:IO 多路復(fù)用 或者 阻塞 IO +多線程

  • IO 多路服用:一個(gè) 線程,跟蹤多個(gè) socket 狀態(tài),哪個(gè)就緒,就讀寫哪個(gè);

  • 阻塞 IO + 多線程:每一個(gè)請(qǐng)求,新建一個(gè)服務(wù)線程

思考:IO 多路復(fù)用 和 多線程 的適用場景?

  • IO 多路復(fù)用:單個(gè)連接的請(qǐng)求處理速度沒有優(yōu)勢(shì),適合 IO 密集型 場景,事件驅(qū)動(dòng)

  • 大并發(fā)量:只使用一個(gè)線程,處理大量的并發(fā)請(qǐng)求,降低上下文環(huán)境切換損耗,也不需要考慮并發(fā)問題,相對(duì)可以處理更多的請(qǐng)求;

  • 消耗更少的系統(tǒng)資源(不需要線程調(diào)度開銷)

  • 適用于長連接的情況(多線程模式長連接容易造成線程過多,造成頻繁調(diào)度)

  • 阻塞IO + 多線程:實(shí)現(xiàn)簡單,可以不依賴系統(tǒng)調(diào)用,適合 CPU 密集型 場景

  • 每個(gè)線程,都需要時(shí)間和空間;

  • 線程數(shù)量增長時(shí),線程調(diào)度開銷指數(shù)增長

Nginx 最大連接數(shù)

基礎(chǔ)背景:

  1. Nginx 是多進(jìn)程模型,Worker 進(jìn)程用于處理請(qǐng)求;

  2. 單個(gè)進(jìn)程的連接數(shù)(文件描述符 fd),有上限(nofile):ulimit -n

  3. Nginx 上配置單個(gè) worker 進(jìn)程的最大連接數(shù):worker_connections 上限為 nofile

  4. Nginx 上配置 worker 進(jìn)程的數(shù)量:worker_processes

因此,Nginx 的最大連接數(shù):

  1. Nginx 的最大連接數(shù):Worker 進(jìn)程數(shù)量 x 單個(gè) Worker 進(jìn)程的最大連接數(shù)

  2. 上面是 Nginx 作為通用服務(wù)器時(shí),最大的連接數(shù)

  3. Nginx 作為反向代理服務(wù)器時(shí),能夠服務(wù)的最大連接數(shù):(Worker 進(jìn)程數(shù)量 x 單個(gè) Worker 進(jìn)程的最大連接數(shù))/ 2。

  4. Nginx 反向代理時(shí),會(huì)建立 Client 的連接和后端 Web Server 的連接,占用 2 個(gè)連接

思考:

每打開一個(gè) socket 占用一個(gè) fd

為什么,一個(gè)進(jìn)程能夠打開的 fd 數(shù)量有限制?

IO 模型

場景:

處理多個(gè)請(qǐng)求時(shí),可以采用:IO 多路復(fù)用 或者 阻塞 IO +多線程

  • IO 多路復(fù)用:一個(gè) 線程,跟蹤多個(gè) socket 狀態(tài),哪個(gè)就緒,就讀寫哪個(gè);

  • 阻塞 IO + 多線程:每一個(gè)請(qǐng)求,新建一個(gè)服務(wù)線程

思考:IO 多路復(fù)用 和 多線程 的適用場景?

  • IO 多路復(fù)用:單個(gè)連接的請(qǐng)求處理速度沒有優(yōu)勢(shì)

  • 大并發(fā)量:只使用一個(gè)線程,處理大量的并發(fā)請(qǐng)求,降低上下文環(huán)境切換損耗,也不需要考慮并發(fā)問題,相對(duì)可以處理更多的請(qǐng)求;

  • 消耗更少的系統(tǒng)資源(不需要線程調(diào)度開銷)

  • 適用于長連接的情況(多線程模式長連接容易造成線程過多,造成頻繁調(diào)度)

  • 阻塞IO + 多線程:實(shí)現(xiàn)簡單,可以不依賴系統(tǒng)調(diào)用。

  • 每個(gè)線程,都需要時(shí)間和空間;

  • 線程數(shù)量增長時(shí),線程調(diào)度開銷指數(shù)增長

select/poll 和 epoll 比較

詳細(xì)內(nèi)容,參考:

  • select poll epoll三者之間的比較

select/poll 系統(tǒng)調(diào)用:

// select 系統(tǒng)調(diào)用  int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);  // poll 系統(tǒng)調(diào)用  int poll(struct pollfd fds[], nfds_t nfds, int timeout);

select:

  • 查詢 fd_set 中,是否有就緒的 fd,可以設(shè)定一個(gè)超時(shí)時(shí)間,當(dāng)有 fd (File descripter) 就緒或超時(shí)返回;

  • fd_set 是一個(gè)位集合,大小是在編譯內(nèi)核時(shí)的常量,默認(rèn)大小為 1024

  • 特點(diǎn):

  • 連接數(shù)限制,fd_set 可表示的 fd 數(shù)量太小了;

  • 線性掃描:判斷 fd 是否就緒,需要遍歷一邊 fd_set;

  • 數(shù)據(jù)復(fù)制:用戶空間和內(nèi)核空間,復(fù)制連接就緒狀態(tài)信息

poll:

  • 解決了連接數(shù)限制:

  • poll 中將 select 中的 fd_set 替換成了一個(gè) pollfd 數(shù)組

  • 解決 fd 數(shù)量過小的問題

  • 數(shù)據(jù)復(fù)制:用戶空間和內(nèi)核空間,復(fù)制連接就緒狀態(tài)信息

  • epoll:event 事件驅(qū)動(dòng)

epoll:event 事件驅(qū)動(dòng)

  • 事件機(jī)制:避免線性掃描

  • 為每個(gè) fd,注冊(cè)一個(gè)監(jiān)聽事件

  • fd 變更為就緒時(shí),將 fd 添加到就緒鏈表

  • fd 數(shù)量:無限制(OS 級(jí)別的限制,單個(gè)進(jìn)程能打開多少個(gè) fd)

select,poll,epoll:

  1. I/O多路復(fù)用的機(jī)制;

  2. I/O多路復(fù)用就通過一種機(jī)制,可以監(jiān)視多個(gè)描述符,一旦某個(gè)描述符就緒(一般是讀就緒或者寫就緒),能夠通知程序進(jìn)行相應(yīng)的讀寫操作。

  3. 監(jiān)視多個(gè)文件描述符

  4. 但select,poll,epoll本質(zhì)上都是同步I/O:

  5. 用戶進(jìn)程負(fù)責(zé)讀寫(從內(nèi)核空間拷貝到用戶空間),讀寫過程中,用戶進(jìn)程是阻塞的;

  6. 異步 IO,無需用戶進(jìn)程負(fù)責(zé)讀寫,異步IO,會(huì)負(fù)責(zé)從內(nèi)核空間拷貝到用戶空間;

Nginx 的并發(fā)處理能力

關(guān)于 Nginx 的并發(fā)處理能力:

  • 并發(fā)連接數(shù),一般優(yōu)化后,峰值能保持在 1~3w 左右。(內(nèi)存和 CPU 核心數(shù)不同,會(huì)有進(jìn)一步優(yōu)化空間) 

“Nginx的事件處理模型怎么理解”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI