目錄:編程
1. Nginx的總體架構windows
2. Nginx的模塊化設計緩存
3. Nginx的請求方式處理安全
4. Nginx事件驅動模型服務器
5. Nginx進程處理模型網絡
Nginx 是一個 免費的,開源的,高性能的 HTTP 服務器和反向代理。以其高性能,穩定性,豐富的功能,簡單的配置和低資源消耗而聞名。Nginx是一個Web服務器,也能夠用做負載均衡器和 HTTP 緩存 。多線程
不少高知名度的網站都使用 Nginx,好比:Netflix , GitHub , SoundCloud , MaxCDN 等。架構
1. Nginx的總體架構併發
1.1. 主進程負載均衡
Nginx 啓動時,會生成兩種類型的進程,一個是主進程 ( master ), 一個 ( windows版本的目前只有一個)或 多個工做進程 ( worker )。
主進程並不處理網絡請求,主要負責調度工做進程 ,也就是圖示的 3 項:
加載配置
啓動工做進程
非停升級
所以,Nginx 啓動之後,查看操做系統的進程列表,咱們就能看到至少有兩個Nginx 進程。
1.2. 工做進程
服務器實際處理網絡請求及響應的是工做進程 ( worker ),在類 unix 系統上, Nginx能夠配置多個worker ,而每一個 worker 進程均可以同時處理數以千計的網絡請求 。
1.3. 模塊化設計
Nginx的worker進程,包括核心和功能性模塊,核心模塊負責維持一個運行循環 ( run-loop ),執行網絡請求處理的 不一樣階段 的模塊功能。
好比: 網絡讀寫 、 存儲讀寫、 內容傳輸 、 外出過濾 ,以及將請求發往上游服務器等。
而其代碼的模塊化設計 ,也使得咱們能夠根據須要對 功能模塊 進行適當的 選擇 和 修改 ,編譯成具備 特定功能的服務器。
1.4. 事件驅動模型
基於 異步及非阻塞的事件驅動模型 ,能夠說是 Nginx 得以得到高併發、高性能的關鍵因素,同時也得益於對 Linux 、 Solaris 及類 BSD 等操做系統內核中 事件通知 及 I/O 性能加強功能 的採用,如 kqueue 、 epoll 及 event ports 。
1.5. 代理(proxy)設計
代理設計,能夠說是 Nginx 深刻骨髓的設計,不管是對於 HTTP ,仍是對於 FastCGI 、 Memcache 、 Redis 等的網絡請求或響應,本質上都採用了 代理機制 。因此, Nginx 天生就是高性能的 代理服務器 。
2. Nginx的模塊化設計
高度模塊化的設計是 Nginx 的架構基礎。 Nginx 服務器被分解爲多個模塊 ,每一個模塊就是一個功能模塊 ,只負責自身的功能,模塊之間嚴格遵循 「高內聚,低耦合」 的原則。
以下圖所示:
2.1. 核心模塊
核心模塊是 Nginx 服務器正常運行 必不可少的模塊,提供錯誤日誌記錄 、 配置文件解析 、 事件驅動機制 、 進程管理 等核心功能。
2.2. 標準HTTP模塊
標準 HTTP 模塊提供 HTTP 協議解析相關的功能,好比: 端口配置 、 網頁編碼設置 、 HTTP響應頭設置 等等。
2.3. 可選HTTP模塊
可選 HTTP 模塊主要用於 擴展 標準的 HTTP 功能,讓 Nginx 能處理一些特殊的服務,好比: Flash 多媒體傳輸 、解析 GeoIP 請求、 網絡傳輸壓縮 、 安全協議 SSL 支持等。
2.4. 郵件服務模塊
郵件服務模塊主要用於支持 Nginx 的 郵件服務 ,包括對 POP3 協議、 IMAP 協議和 SMTP協議的支持。
2.5. 第三方模塊
第三方模塊是爲了擴展 Nginx 服務器應用,完成開發者自定義功能,好比: Json 支持、 Lua 支持等。
3. Nginx的請求方式處理
Nginx 是一個 高性能 的 Web 服務器,可以同時處理大量的併發請求 。它結合多進程機制和 異步機制 ,異步機制使用的是 異步非阻塞方式 ,接下來就給你們介紹一下 Nginx 的 多線程機制 和 異步非阻塞機制 。
3.1. 多進程機制
服務器每當收到一個客戶端時,就有 服務器主進程 ( master process )生成一個 子進程( worker process )出來和客戶端創建鏈接進行交互,直到鏈接斷開,該子進程就結束了。
使用 進程 的好處是 各個進程之間相互獨立 , 不須要加鎖 ,減小了使用鎖對性能形成影響,同時下降編程的複雜度,下降開發成本。
其次,採用獨立的進程,可讓 進程互相之間不會影響 ,若是一個進程發生異常退出時,其它進程正常工做, master 進程則很快啓動新的 worker 進程,確保服務不會中斷,從而將風險降到最低。
缺點是操做系統生成一個 子進程 須要進行 內存複製 等操做,在 資源 和 時間 上會產生必定的開銷。當有 大量請求 時,會致使 系統性能降低 。
3.2. 異步非阻塞機制
每一個 工做進程 使用 異步非阻塞方式 ,能夠處理多個客戶端請求 。
當某個 工做進程 接收到客戶端的請求之後,調用 IO 進行處理,若是不能當即獲得結果,就去處理其餘請求 (即爲非阻塞 ),而客戶端在此期間也無需等待響應 ,能夠去處理其餘事情(即爲異步 )
當 IO 返回時,就會通知此工做進程,該進程獲得通知,暫時掛起當前處理的事務去 響應客戶端請求 。
4. Nginx事件驅動模型
在 Nginx 的 異步非阻塞機制 中, 工做進程在調用 IO 後,就去處理其餘的請求,當 IO 調用返回後,會通知該工做進程 。
對於這樣的系統調用,主要使用 Nginx 服務器的事件驅動模型來實現,以下圖所示:
如上圖所示, Nginx 的 事件驅動模型 由 事件收集器 、 事件發送器 和 事件處理器 三部分基本單元組成。
事件收集器:負責收集 worker 進程的各類 IO 請求;
事件發送器:負責將 IO 事件發送到 事件處理器 ;
事件處理器:負責各類事件的 響應工做 。
事件發送器將每一個請求放入一個 待處理事件列表 ,使用非阻塞 I/O 方式調用 事件處理器來處理該請求。
其處理方式稱爲 「多路 IO 複用方法」 ,常見的包括如下三種: select 模型、 poll模型、 epoll 模型。
5. Nginx進程處理模型
Nginx 服務器使用 master/worker 多進程模式,多線程啓動和執行的流程以下:
主程序Master process啓動後,經過一個 for 循環來接收和處理外部信號
主進程經過 fork() 函數產生 worker 子進程 ,每一個 子進程 執行一個 for 循環來實現 Nginx 服務器 對事件的接收 和 處理
通常推薦 worker 進程數 與 CPU 內核數 一致,這樣一來不存在 大量的子進程 生成和管理任務,避免了進程之間 競爭 CPU 資源 和 進程切換 的開銷。
並且 Nginx 爲了更好的利用 多核特性 ,提供了 CPU 親緣性 的綁定選項,咱們能夠將某 一個進程綁定在某一個核上,這樣就不會由於 進程的切換 帶來 Cache 的失效
對於每一個請求,有且只有一個 工做進程 對其處理。首先,每一個 worker 進程都是從 master進程 fork 過來。在 master 進程裏面,先創建好須要 listen 的 socket(listenfd) 以後,而後再 fork 出多個 worker 進程。
全部 worker 進程的 listenfd 會在 新鏈接 到來時變得 可讀 ,爲保證只有一個進程處理該鏈接,全部 worker 進程在註冊 listenfd 讀事件前搶佔 accept_mutex
搶到 互斥鎖 的那個進程註冊 listenfd 讀事件 ,在讀事件裏調用 accept 接受該鏈接。
當一個 worker 進程在 accept 這個鏈接以後,就開始讀取請求 , 解析請求 , 處理請求,產生數據後,再返回給客戶端 ,最後才斷開鏈接 ,一個完整的請求就是這樣。
咱們能夠看到,一個請求,徹底由 worker 進程來處理,並且只在一個 worker 進程中處理。
以下圖所示:
在 Nginx 服務器的運行過程當中, 主進程 和 工做進程 須要進程交互。交互依賴於 Socket 實現的管道來實現。
5.1. 主進程與工做進程交互
這條管道與普通的管道不一樣,它是由 主進程 指向 工做進程 的單向管道 ,包含主進程向工做進程發出的指令工,做進程 ID 等。同時主進程與外界經過信號通訊 ;每一個子進程具有接收信號 ,並處理相應的事件的能力。
5.2. 工做進程與工做進程交互
這種交互和 主進程-工做進程 交互基本一致,可是會經過主進程間接完成,工做進程之間是相互隔離的。
因此當工做進程 W1 須要向工做進程 W2 發指令時,首先找到 W2 的 進程ID ,而後將正確的指令寫入指向 W2 的 通道,W2 收到信號採起相應的措施。
經過這篇文章,咱們對 Nginx 服務器的 總體架構 有了一個總體的認識。包括其 模塊化的設計、 多進程 和 異步非阻塞 的請求處理方式、 事件驅動模型 等。
經過這些理論知識,才能更好地領悟 Nginx 的設計思想。對於咱們學習 Nginx 來講有很大的幫助。
End
做者:我最喜歡三大框架
來源:
https://my.oschina.net/u/3906190/blog/1859060
本文版權歸做者全部
長按下圖二維碼,即刻關注【狸貓技術窩】
阿里、京東、美團、字節跳動 頂尖技術專家坐鎮
爲IT人打造一個 「有溫度」 的技術窩!