從 Nginx 優秀的核心架構設計,揭秘其為何能支持高并發?

還沒關注?

快動動手指!

聊技術、論職場!

IT人打造一個“有溫度”的 貍貓技術窩

目錄

1. Nginx的整體架構

2. Nginx的模塊化設計

3. Nginx的請求方式處理

4. Nginx事件驅動模型

5. Nginx進程處理模型

在前面

Nginx 是一個 免費的,開源的,高性能的 HTTP 服務器反向代理。以其高性能,穩定性,豐富的功能,簡單的配置和低資源消耗而聞名。Nginx是一個Web服務器,也可以用作負載均衡器和 HTTP 緩存 。

很多高知名度的網站都使用 Nginx,比如:NetflixGitHub , SoundCloud , MaxCDN 等。

從 Nginx 優秀的核心架構設計,揭秘其為何能支持高并發?

正文

1. Nginx的整體架構

從 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 服務器被分解為多個模塊 ,每個模塊就是一個功能模塊 ,只負責自身的功能,模塊之間嚴格遵循 “高內聚,低耦合” 的原則。

如下圖所示:

從 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 優秀的核心架構設計,揭秘其為何能支持高并發?

如上圖所示, Nginx 的 事件驅動模型 由 事件收集器 、 事件發送器 和 事件處理器 三部分基本單元組成。

  • 事件收集器:負責收集 worker 進程的各種 IO 請求;

  • 事件發送器:負責將 IO 事件發送到 事件處理器 ;

  • 事件處理器:負責各種事件的 響應工作 。

事件發送器將每個請求放入一個 待處理事件列表 ,使用非阻塞 I/O 方式調用 事件處理器來處理該請求。

其處理方式稱為 “多路 IO 復用方法” ,常見的包括以下三種: select 模型、 poll模型、 epoll 模型。

5. Nginx進程處理模型

Nginx 服務器使用 master/worker 多進程模式,多線程啟動和執行的流程如下:

  1. 主程序Master process啟動后,通過一個 for 循環來接收和處理外部信號

  2. 主進程通過 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 優秀的核心架構設計,揭秘其為何能支持高并發?

在 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

本文版權歸作者所有

為您推薦

  1. 如何設計一個百萬級用戶的抽獎系統?

  2. 阿里二面:設計一個電商平臺積分兌換系統!

  3. 扎心一問!你憑什么成為top1%的Java工程師

  4. 【干貨走一波】千萬級用戶的大型網站,應該如何設計其高并發架構?

  5. PK光明頂?江湖上流傳的幾大消息隊列門派,到底有什么本質區別?

  6. 扒一扒 JVM垃圾回收機制,拿大廠offer少不了它!

  7. 面試阿里?如果對別人開源的Rocket MQ了如指掌,豈不是很加分?

  8. 百度、騰訊熱門面試題:聊聊Unix與Java的IO模型?(含詳細解析)

  9. 35歲的大齡碼農們,如何才能不被社會淘汰掉?

  10. 一步一圖,帶你走進Netty的世界!

  11. 想要去阿里面試?你必須得跨過JVM這道坎!

  12. 你連Nginx怎么轉發給你請求都說不清楚,還好意思說自己不是CRUD工程師?

長按下圖二維碼,即刻關注【 貍貓技術窩

阿里、京東美團、字節跳動

頂尖技術專家 坐鎮

為IT人打造一個 “有溫度” 的技術窩!

從 Nginx 優秀的核心架構設計,揭秘其為何能支持高并發?

原文 

http://mp.weixin.qq.com/s?__biz=MzU2Njg3OTU1Mg==&mid=2247484133&idx=1&sn=47a6927ec739bfd31fe6bd11f26812ca

本站部分文章源于互聯網,本著傳播知識、有益學習和研究的目的進行的轉載,為網友免費提供。如有著作權人或出版方提出異議,本站將立即刪除。如果您對文章轉載有任何疑問請告之我們,以便我們及時糾正。

PS:推薦一個微信公眾號: askHarries 或者qq群:474807195,里面會分享一些資深架構師錄制的視頻錄像:有Spring,MyBatis,Netty源碼分析,高并發、高性能、分布式、微服務架構的原理,JVM性能優化這些成為架構師必備的知識體系。還能領取免費的學習資源,目前受益良多

轉載請注明原文出處:Harries Blog? » 從 Nginx 優秀的核心架構設計,揭秘其為何能支持高并發?

贊 (0)
分享到:更多 ()

評論 0

  • 昵稱 (必填)
  • 郵箱 (必填)
  • 網址
2013平特肖公式