您當前的位置:首頁 > 舞蹈

【效能調優專題】【Nginx調優】【Nginx快速掌握】【Nginx原理】

作者:由 一隻堅持學習的人 發表于 舞蹈時間:2020-07-22

基本原理

Nginx 的程序模型

【效能調優專題】【Nginx調優】【Nginx快速掌握】【Nginx原理】

Nginx 伺服器,正常執行過程中:

多程序

:一個 Master 程序、多個 Worker 程序

Master 程序

:管理 Worker 程序

對外介面:接收

外部的操作

(訊號)

對內轉發:根據

外部的操作

的不同,透過

訊號

管理 Worker

監控:監控 worker 程序的執行狀態,worker 程序異常終止後,自動重啟 worker 程序

Worker 程序

:所有 Worker 程序都是平等的

實際處理:網路請求,由 Worker 程序處理;

Worker 程序數量:在 nginx。conf 中配置,一般設定為

核心數

,充分利用 CPU 資源,同時,避免程序數量過多,避免程序競爭 CPU 資源,增加上下文切換的損耗。

思考:

請求是連線到 Nginx,Master 程序負責處理和轉發?

如何選定哪個 Worker 程序處理請求?請求的處理結果,是否還要經過 Master 程序?

【效能調優專題】【Nginx調優】【Nginx快速掌握】【Nginx原理】

HTTP 連線建立和請求處理過程:

Nginx 啟動時,Master 程序,載入配置檔案

Master 程序,初始化監聽的 socket

Master 程序,fork 出多個 Worker 程序

Worker 程序,競爭新的連線,獲勝方透過三次握手,建立 Socket 連線,並處理請求

Nginx 高效能、高併發:

Nginx 採用:

多程序

+

非同步非阻塞

方式(

IO 多路複用

epoll)

請求的完整過程:

建立連線

讀取請求:解析請求

處理請求

響應請求

請求的完整過程,對應到底層,就是:讀寫 socket 事件

Nginx 的事件處理模型

request:Nginx 中 http 請求。

基本的 HTTP Web Server 工作模式:

接收請求

:逐行讀取

請求行

請求頭

,判斷段有請求體後,讀取

請求體

處理請求

返回響應

:根據處理結果,生成相應的 HTTP 請求(

響應行

響應頭

響應體

Nginx 也是這個套路,整體流程一致。

【效能調優專題】【Nginx調優】【Nginx快速掌握】【Nginx原理】

模組化體系結構

【效能調優專題】【Nginx調優】【Nginx快速掌握】【Nginx原理】

nginx的模組根據其功能基本上可以分為以下幾種型別:

event module

: 搭建了獨立於作業系統的事件處理機制的框架,及提供了各具體事件的處理。包括ngx_events_module, ngx_event_core_module和ngx_epoll_module等。nginx具體使用何種事件處理模組,這依賴於具體的作業系統和編譯選項。

phase handler

: 此型別的模組也被直接稱為handler模組。主要負責處理客戶端請求併產生待響應內容,比如ngx_http_static_module模組,負責客戶端的靜態頁面請求處理並將對應的磁碟檔案準備為響應內容輸出。

output filter

: 也稱為filter模組,主要是負責對輸出的內容進行處理,可以對輸出進行修改。例如,可以實現對輸出的所有html頁面增加預定義的footbar一類的工作,或者對輸出的圖片的URL進行替換之類的工作。

upstream

: upstream模組實現反向代理的功能,將真正的請求轉發到後端伺服器上,並從後端伺服器上讀取響應,發回客戶端。upstream模組是一種特殊的handler,只不過響應內容不是真正由自己產生的,而是從後端伺服器上讀取的。

load-balancer

: 負載均衡模組,實現特定的演算法,在眾多的後端伺服器中,選擇一個伺服器出來作為某個請求的轉發伺服器。

常見問題剖析

Nginx vs. Apache

nginx vs。 apache:

http://www。

oschina。net/translate/n

ginx-vs-apache

網路 IO 模型:

nginx:IO 多路複用,epoll(freebsd 上是 kqueue )

高效能

高併發

佔用系統資源少

apache:阻塞 + 多程序/多執行緒

更穩定,bug 少

模組更豐富

場景:

處理多個請求時,可以採用:

IO 多路複用

或者

阻塞 IO

+

多執行緒

IO 多路服用

一個

執行緒

,跟蹤多個 socket 狀態,哪個

就緒

,就讀寫哪個;

阻塞 IO

+

多執行緒

:每一個請求,新建一個服務執行緒

思考

IO 多路複用

多執行緒

的適用場景?

IO 多路複用

:單個連線的請求處理速度沒有優勢,適合

IO 密集型

場景,事件驅動

大併發量

:只使用一個執行緒,處理大量的併發請求,降低

上下文環境

切換損耗,也不需要考慮併發問題,相對可以處理更多的請求;

消耗更少的系統資源(不需要

執行緒排程開銷

適用於

長連線

的情況(多執行緒模式

長連線

容易造成

執行緒過多

,造成

頻繁排程

阻塞IO

+

多執行緒

:實現簡單,可以不依賴系統呼叫,適合

CPU 密集型

場景

每個執行緒,都需要時間和空間;

執行緒數量增長時,執行緒排程開銷指數增長

Nginx 最大連線數

基礎背景:

Nginx 是多程序模型,Worker 程序用於處理請求;

單個程序的連線數(檔案描述符 fd),有上限(

nofile

):

ulimit -n

Nginx 上配置單個 worker 程序的最大連線數:

worker_connections

上限為

nofile

Nginx 上配置 worker 程序的數量:

worker_processes

因此,Nginx 的最大連線數:

Nginx 的最大連線數:

Worker 程序數量

x

單個 Worker 程序的最大連線數

上面是 Nginx 作為通用伺服器時,最大的連線數

Nginx 作為

反向代理

伺服器時,能夠服務的最大連線數:(

Worker 程序數量

x

單個 Worker 程序的最大連線數

)/ 2。

Nginx 反向代理時,會建立

Client 的連線

後端 Web Server 的連線

,佔用 2 個連線

思考:

每開啟一個 socket 佔用一個 fd

為什麼,

一個程序

能夠開啟的 fd 數量有限制?

附錄

HTTP 請求和響應

HTTP 請求:

請求行:

method

uri

http version

請求頭

請求體

HTTP 響應:

響應行:

http version

status code

響應頭

響應體

IO 模型

場景:

處理多個請求時,可以採用:

IO 多路複用

或者

阻塞 IO

+

多執行緒

IO 多路服用

一個

執行緒

,跟蹤多個 socket 狀態,哪個

就緒

,就讀寫哪個;

阻塞 IO

+

多執行緒

:每一個請求,新建一個服務執行緒

思考:

IO 多路複用

多執行緒

的適用場景?

IO 多路複用

:單個連線的請求處理速度沒有優勢

大併發量

:只使用一個執行緒,處理大量的併發請求,降低

上下文環境

切換損耗,也不需要考慮併發問題,相對可以處理更多的請求;

消耗更少的系統資源(不需要

執行緒排程開銷

適用於

長連線

的情況(多執行緒模式

長連線

容易造成

執行緒過多

,造成

頻繁排程

阻塞IO

+

多執行緒

:實現簡單,可以不依賴系統呼叫。

每個執行緒,都需要時間和空間;

執行緒數量增長時,執行緒排程開銷指數增長

select/poll 和 epoll 比較

詳細內容,參考:

select poll epoll三者之間的比較

select/poll 系統呼叫:

// select 系統呼叫

int

select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);

// poll 系統呼叫

int poll(struct pollfd fds[],

nfds_t nfds,

int timeout);

select

查詢 fd_set 中,是否有

就緒

fd

,可以設定一個

超時時間

,當有 fd (File descripter) 就緒或超時返回;

fd_set 是一個

位集合

,大小是在

編譯核心

時的常量,預設大小為 1024

特點:

連線數限制

,fd_set 可表示的 fd 數量太小了;

線性掃描

:判斷 fd 是否就緒,需要遍歷一邊 fd_set;

資料複製

:使用者空間和核心空間,複製

連線就緒狀態

資訊

poll

解決了

連線數限制

poll 中將 select 中的 fd_set 替換成了一個 pollfd

陣列

解決

fd 數量過小

的問題

資料複製

:使用者空間和核心空間,複製

連線就緒狀態

資訊

epoll

: event 事件驅動

事件機制

:避免

線性掃描

為每個 fd,

註冊

一個

監聽事件

fd 變更為

就緒

時,將 fd 新增到

就緒連結串列

fd 數量

:無限制(OS 級別的限制,單個程序能開啟多少個 fd)

select,poll,epoll:

I/O多路複用

的機制;

I/O多路複用

就透過一種機制,可以監視多個描述符,一旦某個描述符就緒(一般是讀就緒或者寫就緒),能夠通知程式進行相應的讀寫操作。

監視

多個檔案描述符

但select,poll,epoll本質上都是

同步I/O

使用者程序

負責

讀寫

(從

核心空間

複製到

使用者空間

),讀寫過程中,使用者程序是阻塞的;

非同步 IO

,無需使用者程序負責讀寫,非同步IO,會負責從

核心空間

複製到

使用者空間

Nginx 的併發處理能力

關於 Nginx 的併發處理能力:

併發連線數,一般最佳化後,峰值能保持在 1~3w 左右。(記憶體和 CPU 核心數不同,會有進一步最佳化空間)

標簽: 請求  程序  io  FD  nginx