nginx 實現高性能低消耗的原理

Nginx 是一個輕量級的HTTP 服務程序,相比其他服務器程序如Apache,Nginx佔用內存少,穩定性高,併發處理能力強。同時Nginx 還是一個反向代理服務程序,和郵件代理服務程序。Nginx具有豐富的模塊庫、靈活的配置、較低資源消耗等優點。下面,我們一起深入看一下Nginx的工作機制

1. Nginx 如何實現高性能低消耗的呢?

我們從以下幾個方面說明以下:

網絡事件處理機制

  • Nginx 採用異步非阻塞的方式處理請求,可以同時處理上萬的請求
  • Nginx 支持 select/epoll 等流行事件處理機制,根據系統環境自動選擇
  • Nginx 採用獨立於系統的事件處理機制,能夠高效處理請求

資源分配技術

  • Nginx 採用分階段資源分配技術,使得它的CPU和內存消耗非常低

多核處理優化

  • Nginx 默認採用多進程啓動模式
  • Nginx 包含Master 進程 和 Worker 進程
  • 能夠充分利用 SMP 對稱多處理的優勢,減少Worker進程磁盤I/O的阻塞
  • Nginx 支持Worker進程和CPU內核 一一對應綁定,避免進程上下文的切換致使cache失效

基於上面提到技術,以及Nginx很多地方的優化,讓Nginx成爲最快的HTTP服務器。

2.Nginx的進程模型

在Nginx的技術架構中,進程模型是至關重要的一部分。接下來,我們一起看看Nginx進程模型,以及它們的工作機制。

Linux 系統中,Nginx默認以守護進程daemon方式啓動,默認採用多進程方式。Nginx包括兩種類型的進程:

  • Master 進程,數量只有一個,管理Nginx本身和Worker進程
  • Worker 進程,數量一般和CPU核數相等,Nginx的所有請求處理,均是在Worker進程中完成

下面,我們分別深入看一下Master和Worker進程。

2.1 Master 進程工作機制

在Nginx啓動時,Master進程創建,主要負責初始化Nginx和相關模塊、fork Worker進程、接收處理外界信號等工作。

Nginx的初始化過程:

  • 解析配置文件,這是Nginx初始化最重要的一個環節
  • 調用各個配置指令回調函數,完成各個模塊的配置、相互關聯等
  • 建立listen 的 socket(listenfd)
  • 準備工作都完成後,fork worker子進程和cache子進程

Master 進程信號處理機制
我們通過kill命令發送信號給Nignx Master 進程,看看Master進程如何處理:

分析流程:

  • Master 進程接收到 HUP 信號
  • Master 進程重新加載配置文件
  • Master 進程啓動新的Worker進程
  • Master 進程發送信號給Worker 進程
  • 老的Worker進程不再接收新的請求
  • 老的Worker進程處理完當前請求,退出
  • 至此,Nginx完成平滑重啓

注意:Nginx 0.8 版本以後,提供了 -s參數,用於管理Nginx服務的停止和重啓,注意line 11:

2.2 Worker 進程工作機制

Worker進程負責所有請求的處理工作,我們通過一個HTTP請求,來梳理一下Worker的工作流程:

  • 新的請求到來:所有的Work進程的listenfd都會變得可讀
  • 竟搶互斥鎖:所有 Worker 進程在註冊listenfd讀事件前,要先搶accept_mutex
  • 搶到互斥鎖的Worker,註冊listenfd讀事件,在事件中調用accept接受該連接
  • 拿到請求後,Worker進程開始讀取請求,解析請求,處理請求,產生數據,再返回給客戶端
  • Worker進程斷開連接

需要注意:一個HTTP請求,完全由Worker進程處理,而且只在一個Worker中處理

2.3 Master-Worker 進程架構機制的優勢有哪些??

對於每個Worker 進程來說,獨立的進程,不需要加鎖,節約鎖導致的資源開銷;worker進程之間,互不干擾,平滑重啓就是很好的例子,服務不中斷。

2.4 網絡事件處理機制

Nginx 採用的是異步非阻塞事件處理機制,支持select/poll/epoll/kqueue 等等。Nginx 同時會監控多個事件,調用他們是阻塞的。但是調用有超時時間,在超時時間內,如果有事件準備好了,就返回,否則重新放入epoll中。當讀寫返回EAGAIN時,事件將會被再次放入epoll中。

處理線程只有一個,同時處理的請求也只有一個,所謂多請求併發,只是在不斷的切換請求而已。雖然是切換,但這種切換不涉及上下文切換,相比十分輕量。更多的併發,只是會佔用更多的內存。

進程相關的還有,信號和定時器,這部分另外單獨講解。

3. Nginx 包含哪些模塊

Nginx是模塊化架構的服務,豐富的模塊,鬆散耦合,也讓Nginx更加強大!我看看Nginx 都有哪些模塊

  • 內核模塊
    實現了底層的通訊協議,爲其他模塊/進程構建運行環境、協作基礎,打開listen 的端口,啓動worker進程
  • HTTP/Mail模塊
    兩個特殊模塊,位於內核模塊和各功能模塊間;在內核模塊之上實現了另一層的抽象;處理HTTP/MAIL協議事件;確保調用功能模塊順序正確。
  • Event模塊
    負責監聽accept後建立的連接,對讀寫事件進行添加刪除;與非阻塞 I/O 模型結合使用;支持select/poll/epoll/kqueue等;注意驚羣效應,後面有解釋。
  • Handler模塊
    負責接受客戶端請求併產生輸出;通過配置文件中location指令配置 content handler 模塊。
  • Filter模塊
    負責輸出內容處理,修改輸出內容;Fiter模塊在獲取回覆內容之後,向用戶發送響應之前,執行處理動作;調用順序在編譯時就確定了。
  • Upstream模塊
    實現反向代理的功能,負責將請求轉發到後端服務器上,並讀取響應,發回客戶端;跨越單機的限制,完成網絡數據的接收、處理和轉發;
  • LoadBalancer模塊
    根據配置指定算法,在衆多的後端服務器中選擇一個,完成請求的轉發服務器;都有哪些算法呢?

驚羣效應:

  • 當內核 accept 一個連接時,會喚醒所有等待中的進程
  • 但實際上只有一個進程能獲取連接,其他的進程都是被無效喚醒的
  • 所以 Nginx 採用了自有的一套 accept 加鎖機制,避免多個進程同時調用 accept
  • Nginx 多進程的鎖在底層默認是通過 CPU 自旋鎖來實現。如果操作系統不支持自旋鎖,就採用文件鎖。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章