Nginx基礎流程與啓動過程解析

最近在學習Nginx源碼,由於時間有限,主要看主體邏輯流程,事件模塊,HTTP模塊等重要模塊。本章首先對Nginx啓動過程做詳細分析。

Nginx架構設計理念

Nginx的架構設計思想非常的好,很適合高性能服務器的要求,這種服務器的特點在於同時注重系統的整體性能和單次服務的延時性,而Nginx的出現完美填補了這一塊的空缺。

模塊化

Nginx設計的最大特點是模塊化,具體分成http模塊、http過濾模塊、event模塊、core模塊、mail模塊等。這樣做的好處在於系統的可拓展性變高,如果想要增加功能,可以直接增加一個模塊,並將其加入即可。同時,降低模塊之間的耦合程度,提高模塊自身的內聚程序,將系統的服務功能分散到不同的模塊之間,這樣的設計也符合軟件工程中的設計概念。

進程模型

Nginx採用的是多進程服務器模型,系統啓動的時候只會有一個master進程,在conf文件中可以指定啓動的worker進程數目(一般而言,推薦worker進程的數目爲cpu核數),從而形成單一master進程管理多個worker進程的模型。
這裏就有一個問題,一般的高性能io模型都是coroutines + threadpool 、或者one loop per thread + threadpool(多線程),簡單而言線程之間的切換開銷較小,而且同個進程的線程之間有很多資源共享,這樣就爲了高性能提供了基礎。那多進程的io模型如何實現高性能?這裏貼一份知乎大神的解答。

作者:linuor
鏈接:https://www.zhihu.com/question/22062795/answer/20197329
來源:知乎
如果一個server採用一個進程負責一個request的方式,那麼進程數就是併發數。那麼顯而易見的,就是會有很多進程在等待中。等什麼?最多的應該是等待網絡傳輸。其缺點題主應該也感覺到了,此處不述。而nginx 的異步非阻塞工作方式正是利用了這點等待的時間。在需要等待的時候,這些進程就空閒出來待命了。因此表現爲少數幾個進程就解決了大量的併發問題。
nginx是如何利用的呢,簡單來說:同樣的4個進程,如果採用一個進程負責一個request的方式,那麼,同時進來4個request之後,每個進程就負責其中一個,直至會話關閉。期間,如果有第5個request進來了。就無法及時反應了,因爲4個進程都沒幹完活呢,因此,一般有個調度進程,每當新進來了一個request,就新開個進程來處理。
nginx不這樣,每進來一個request,會有一個worker進程去處理。但不是全程的處理,處理到什麼程度呢?處理到可能發生阻塞的地方,比如向上遊(後端)服務器轉發request,並等待請求返回。那麼,這個處理的worker不會這麼傻等着,他會在發送完請求後,註冊一個事件:“如果upstream返回了,告訴我一聲,我再接着幹”。於是他就休息去了。此時,如果再有request 進來,他就可以很快再按這種方式處理。而一旦上游服務器返回了,就會觸發這個事件,worker纔會來接手,這個request纔會接着往下走。

簡單而言,異步(回調事件)、非阻塞(每個進程執行期間不允許阻塞)、epoll(多路複用基礎)等機制聯合起來導致了nginx的高性能。

主要應用功能

Nginx目前在工業界也有很好的應用,但是基本上就會作爲靜態資源服務,或者作爲內網與外網的第一個通道,作爲負載均衡或者反向代理的服務器,接下來簡單介紹其主要應用功能。

反向代理

反向代理服務器的功能是將外網上的請求轉發到內網的服務器中,作爲外網和內網之間的橋樑。理解正向代理和反向代理區別最好的一句話就是:正向代理是代理客戶端,反向代理是代理服務器。反向代理有很多好處:

  1. 可以提高內部服務器集羣的安全性。代理服務器作爲內部服務器的訪問的一個接口,所有對內部服務器的訪問都要通過反向代理服務進行轉發,而反向代理服務器就可以作爲第一層的保護屏障。
  2. 一些訪問量大的靜態資源可以直接放在反向代理服務器,減少帶寬壓力。
  3. 反向代理服務器可以規劃好內部路由請求。當內部集羣有多個系統分佈在不同的機器上,如果想要通過外網訪問這些服務(前提是防火牆允許的情況下),可以很好地利用反向代理請求。

負載均衡

負載均衡從名字就可以看出其作用,當多臺服務器提供相同的功能時候,有時候可能出現所有請求都到離其最近的服務器上,這樣就會導致部分服務器負載很大,而部分服務器沒有提供服務,這時候就需要負載均衡服務器。常用於將工作負載分佈到多個服務器來提高網站、應用、數據庫或其他服務的性能和可靠性。
這裏就涉及到負載均衡算法(通過什麼方式將請求分發給不同的服務器)
常見的負載均衡算法有三種:

  1. 輪詢算法(Round Robin)按順序輪詢的分配請求給服務器
  2. 最小連接算法(Least Connections)將請求分配給連接數最小的服務器
  3. hash ip算法(Source)根據請求的ip地址,可以保證每次請求hash後分配給固定的服務器

動靜分離

通常來說,Nginx一般可以存儲靜態資源(如html,css,js),因爲這種資源是每次請求都要獲取的,而動態資源則放到不同的服務器上(常用tomcat代理)。

Nginx啓動過程概述

Nginx啓動過程如下圖所示(nginx.c):
nginx啓動過程

  1. Nginx在啓動的時候首先會解析命令行,處理各種參數。然後主要是確定配置文件nginx.conf路徑。
  2. 第二步就是判斷是否需要平滑升級。
  3. 然後就是各種初始化。
  4. 然後判斷nginx是否是以單進程運行,如果是則調用所有模塊的init方法,然後會進行正常的工作模式,如果是master-worker模式則會後面具體分析。

master進程

master進程的工作室管理worker進程,master不會去處理網絡事件,只會通過信號管理worker進程,其主要的工作在ngx_master_process_cycle(ngx_process_cycle.c)函數中,流程如下:
master進程流程
master的工作很簡單,一開始初始化好信號,然後sigprocmask阻塞這些關聯的信號,以防其阻礙到fork,然後再循環中,每次sigsuspend掛起進程等待信號,當有信號來的時候,喚起master進程,進程隨機查看標誌位分別進行處理。
這裏標誌主要包括:reap、terminate、quit、reconfigure、restart、reopen、change_binary、noaccept。

worker進程

worker進程主要用於處理網絡事件。通過master進程中調用ngx_start_worker_processes函數,ngx_start_worker_processes函數調用ngx_spawn_process函數,實際上fork的工作是在ngx_spawn_process函數中進行的,然後worker進程的主循環是在函數ngx_worker_process_cycle中,流程如下:
worker進程流程圖
worker的工作也很簡單,基本上上圖說明了一切。重點關注幾個標誌位的意義即可。

參考:

  1. 知乎
  2. nginx啓動
  3. nginx開發從入門到精通
  4. 深入理解nginx
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章