Nginx 的進程結構,你明白嗎?

来源:https://www.cnblogs.com/wupeixuan/archive/2019/11/13/11846400.html
-Advertisement-
Play Games

Nginx 進程結構 這篇文章我們來看下 Nginx 的進程結構,Nginx 其實有兩種進程結構: 單進程結構 多進程結構 單進程結構實際上不適用於生產環境,只適合我們做開發調試使用。因為在生產環境中我們必須保持 Nginx 足夠健壯以及 Nginx 可以利用多核的一個特性,而單進程的 Nginx ...


Nginx 進程結構

這篇文章我們來看下 Nginx 的進程結構,Nginx 其實有兩種進程結構:

  • 單進程結構
  • 多進程結構

單進程結構實際上不適用於生產環境,只適合我們做開發調試使用。因為在生產環境中我們必須保持 Nginx 足夠健壯以及 Nginx 可以利用多核的一個特性,而單進程的 Nginx 是做不到這一點的,所以預設的配置中都是打開為多進程的 Nginx。

我們來看一下,多進程的 Nginx 結構中它的進程模型是怎樣的。

Nginx進程結構

多進程中的 Nginx 進程架構如下圖所示,會有一個父進程(Master Process),它會有很多子進程(Child Processes),這些子進程會分為兩類:

  • worker 進程
  • cache 相關的進程

為什麼 Nginx 採用多進程結構而不是多線程結構呢?

因為 Nginx 最核心的一個目的是要保持高可用性、高可靠性,而當 Nginx 如果使用的是多線程結構的時候,因為線程之間是共用同一個地址空間的,所以當某一個第三方模塊引發了一個地址空間導致的段錯誤時、在地址越界出現時,會導致整個 Nginx 進程全部掛掉。而當採用多進程模型時,往往不會出現這樣的問題。從上圖可以看到 Nginx 在做進程設計時,同樣遵循了實現高可用、高可靠這樣的一個目的。

比如說在 master 進程中,通常第三方模塊是不會在 master 部分加入自己的功能代碼的。雖然 Nginx 在設計時,允許第三方模塊在 master 進程中添加自己獨有的、自定義的一些方法,但是通常沒有第三方模塊這麼做。

master 進程被設計用來的目的是做 worker 進程的管理的,也就是所有的 worker 進程是處理真正的請求的,而 master 進程負責監控每個 worker 進程是不是在正常的工作、需不需要做重新載入配置文件、需不需要做熱部署。

而 cache (緩存)是在多個 worker 進程間共用的,而且緩存不僅要被 worker 進程使用,還要被 cache manager 和 cache loader進程 使用。cache manager 和 cache loader 也是為反向代理時,後端發來的動態請求做緩存所使用的,cache loader 只是用來做緩存的載入、cache manager 用來做緩存的管理。實際上每個請求處理時,使用到緩存還是由 worker 進程來進行的。

這些進程間的通訊,都是使用共用記憶體來解決的。可以看到cache manager 和 cache loader各有一個進程,master 進程因為是父進程,所以肯定只有一個。那麼 worker 進程為什麼會有很多呢?這是因為 Nginx 採用了事件驅動引擎以後,他希望每一個 worker 進程從頭到尾占有一顆CPU,所以往往不止要把 worker 進程的數量配置與我們伺服器上的 CPU核數一致以外,還需要把每一個worker進程與某一顆CPU核綁定在一起,這樣可以更好的使用每顆CPU核上面的CPU緩存來減少緩存失效的命中率。

以上就是 Nginx 的進程結構的介紹,瞭解這些後更有助於我們去配置 Nginx。

剛纔我們介紹了 Nginx 使用了多進程模型,由 master 作為父進程啟動許多子進程,也知道了 Nginx 父子進程之間是通過信號來管理的,接下來通過一個實例給大家直觀的看下父子進程以及信號之間是如何工作的。

Nginx 的進程結構實例

首先啟動 Nginx,併在 Nginx 中啟動了兩個 worker 進程,通過 ps 命令可以看到當前進程 PID 和父進程 PID,有一個 nginx master 進程是由 root 用戶起的,進程 PID 是 2368。還有兩個 worker 進程和 cache 進程,它們是由 2368 進程起來的。它們的進程 PID 分別為 8652,8653,8655。

現在我們使用 ./sbin/nginx -s reload 命令,會把之前的 worker 進程和 cache 進程優雅的退出,然後再使用的新的配置項啟動新的 worker 進程,這裡我們並沒有改變配置,但是我們可以看到老的三個子進程會退出,並生成新的子進程。

可以看到,之前的三個子進程,現在已經都不在了,反而由 2368 新起了 8657,8658,8660 三個子進程。

[root@wupx nginx]# ps -ef|grep nginx
root      2368     1  0 Sep21 ?        00:00:00 nginx: master process /usr/sbin/nginx
root      4751  4688  0 11:41 pts/0    00:00:00 grep --color=auto nginx
nginx     8652  2368  0 Nov12 ?        00:00:00 nginx: worker process
nginx     8653  2368  0 Nov12 ?        00:00:00 nginx: worker process
nginx     8655  2368  0 Nov12 ?        00:00:00 nginx: cache manager process
[root@wupx nginx]# ./sbin/nginx -s reload
[root@wupx nginx]# ps -ef|grep nginx
root      2368     1  0 Sep21 ?        00:00:00 nginx: master process /usr/sbin/nginx
root      4753  4688  0 11:43 pts/0    00:00:00 grep --color=auto nginx
nginx     8657  2368  0 Nov12 ?        00:00:00 nginx: worker process
nginx     8658  2368  0 Nov12 ?        00:00:00 nginx: worker process
nginx     8660  2368  0 Nov12 ?        00:00:00 nginx: cache manager process

執行命令之後可以看到 worker 的 PID 已經變化了(之前講過 ./sbin/nginx -s reloadkill -SIGHUP 作用是一樣的。)。

kill -SIGTERM 是向現有的 worker 進程發送退出的信號,對應的 worker 進程就會退出;進程在退出時,會自動向父進程 master 發送一個退出信號,master 就知道他的子進程退出了,然後新起一個 worker 進程。

[root@wupx nginx]# ps -ef|grep nginx
root      2368     1  0 Sep21 ?        00:00:00 nginx: master process /usr/sbin/nginx
root      4753  4688  0 11:43 pts/0    00:00:00 grep --color=auto nginx
nginx     8657  2368  0 Nov12 ?        00:00:00 nginx: worker process
nginx     8658  2368  0 Nov12 ?        00:00:00 nginx: worker process
nginx     8660  2368  0 Nov12 ?        00:00:00 nginx: cache manager process
[root@wupx nginx]# kill -SIGTERM 8658
[root@wupx nginx]# ps -ef|grep nginx
root      2368     1  0 Sep21 ?        00:00:00 nginx: master process /usr/sbin/nginx
root      4753  4688  0 11:44 pts/0    00:00:00 grep --color=auto nginx
nginx     8657  2368  0 Nov12 ?        00:00:00 nginx: worker process
nginx     8660  2368  0 Nov12 ?        00:00:00 nginx: cache manager process
nginx     8663  2368  0 Nov12 ?        00:00:00 nginx: worker process

通過實例演示,我們可以看到 Nginx 的進程結構以及 Nginx 使用信號的方式,其實命令行中的許多子命令就是再向 master 進程發送信號而已。

進程模型


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前沿:參考ES6語法的async/await的處理機制 先上一段代碼 1 function getMoney(){ 2 var money=[100,200,300] 3 for( let i=0; i<money.length; i++){ 4 compute.exec().then(()=>{ ...
  • 閉包的實現原理和作用 1、閉包的概念:指有權訪問另一個函數作用域中的變數的函數,一般情況就是在一個函數中包含另一個函數。 2、閉包的作用:訪問函數內部變數、保持函數在環境中一直存在,不會被垃圾回收機制處理 因為函數內部聲明 的變數是局部的,只能在函數內部訪問到,但是函數外部的變數是對函數內部可見的, ...
  • 讀取數據://ajax去伺服器端校驗$.ajax({ type:"post", url:"http://", data:{deviceid:1}, dataType:'json', success : function(data) { var jsonText = data; var ab= eva ...
  • 通過日常的工作記錄NPM常用命令,不斷的學習,不斷總結,未完待續…… ...
  • 場景 Nginx入門簡介和反向代理、負載均衡、動靜分離理解: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/102790862 Ubuntu Server 16.04 LTS上怎樣安裝下載安裝Nginx並啟動: https://b ...
  • Eureka作為服務註冊與發現的組件,Eureka2.0已經閉源了,但是本教程還是以Eureka為核心進行展開。 1、三個模塊 Spring Cloud Eureka是Spring Cloud Netflix微服務套件之一,基於Netflix Eureka做了二次封裝,主要負責完成微服務架構中的服務 ...
  • windows安裝python flask虛擬環境: 安裝虛擬環境主要是為了防止不同python版本之間衝突的問題,虛擬環境安裝的包包不會對外部真實環境產生任何作用,只會作用於虛擬環境。這樣,一個flask框架應用對應一個虛擬環境,虛擬環境不會幹擾外部真實環境,同時也不會受外部環境干擾。 1、安裝v ...
  • 以思維導圖的方式呈現: 鏈接: https://naotu.baidu.com/file/9b3e739442ffb9f5bc5c3cee2b1a3489 png圖片: 作者:流浪者 日期:2019-11-13 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...