Nginx 訊號控制

Mondo 科技 更新 2024-01-31

在生產環境中,nginx 一般採用乙個主程序和多個工作程序的模式,其中主程序不需要處理網路事件,不負責業務的執行,而只是對工作程序進行管理,以實現重啟服務、平滑公升級、替換日誌檔案等功能, 和配置檔案實時生效,同時使用工作程序提供服務,如靜態檔案服務、反向**等功能。

那麼nginx是如何實現master重啟服務的,平滑公升級,日誌檔案替換,配置檔案實時生效呢?此外,主程序如何實時通知工作程序重啟服務、平滑公升級、替換日誌檔案、可配置檔案生效?答案是訊號。 下面我們來看一下nginx是如何結合**做到上述的。

因為nginx使用訊號來實現平滑公升級、日誌檔案替換、配置檔案實時效果、重啟服務等功能,所以nginx啟動過程中使用的訊號會註冊到作業系統核心中,其**實現如下:

int ngx_cdecl

main(int argc, char *const *ar**)

初始化訊號*

if (ngx_init_signals(cycle->log) != ngx_ok)

ngx init signals() 的實現方式如下:

ngx_int_t

ngx_init_signals(ngx_log_t *log)

ngx_signal_t *sig;

struct sigaction sa;Linux 核心使用的訊號。

遍歷 signals 陣列,將所有 nginx 支援的訊號*註冊到核心

for (sig = signals; sig->signo != 0; sig++)

return ngx_ok;

從 ngx init signals() 函式的實現中,我們可以看到 nginx 通過呼叫 sigaction() 將支援的訊號註冊到作業系統核心中,當核心捕獲到對應的訊號時,會呼叫 ** 函式進行訊號處理。 從**中可以看出,其實nginx支援的所有訊號對應的處理程式都是一樣的,即ngx訊號hanlder()。 在這個函式中,nginx 中的訊號會根據鎖的訊號設定乙個對應的全域性變數,然後在主程序的處理迴圈中根據這個全域性變數執行相應的動作,後面會描述。

一般來說,當 nginx 程序(包括 master 程序和 worker 程序)已經在環境中執行時,所謂的平滑公升級、日誌檔案或配置檔案的替換實時生效等管理功能。 那麼nginx是如何從命令列控制這些特性的呢?nginx 的做法是啟動乙個新的 nginx 程序,將相應的控制訊號傳送到環境中已經存在的主程序,以便現有的服務可以執行相應的動作。 那麼,新的 nginx 程序如何向環境中已有的主程序發出訊號呢?其**實現如下:

int ngx_cdecl

main(int argc, char *const *ar**)

"nginx -s xxx"*/

if (ngx_signal)

從實現中可以看出,新的 nginx 程序在執行後返回退出,因為這個新啟動的程序是用來傳送訊號的。 那麼,新程序如何向現有主程序發出訊號呢?答案是通過終止系統呼叫。 一般來說,有兩個步驟:第乙個是獲取儲存在nginx中的正在執行的master程序pid 檔案中的 pid,即 ngx 訊號 process() 函式的作用,實現如下:

ngx_int_t

ngx_signal_process(ngx_cycle_t *cycle, char *sig)

ssize_t n;

ngx_pid_t pid;

ngx_file_t file;

ngx_core_conf_t *ccf;

u_char buf[ngx_int64_len + 2];

獲取核心模組中儲存的配置項的結構指標*

ccf = (ngx_core_conf_t *)ngx_get_conf(cycle->conf_ctx, ngx_core_module);

ngx_memzero(&file, sizeof(ngx_file_t));

file.name = ccf->pid;CCF->PID 是 nginxPID 檔案。

file.log = cycle->log;

以可讀的方式開啟 nginx。PID 檔案。

file.fd = ngx_open_file(file.name.data, ngx_file_rdonly,ngx_file_open, ngx_file_default_access);

讀檔案 * n = ngx 讀檔案(&file, buf, ngx int64 len + 2, 0);

if (ngx_close_file(file.fd) == ngx_file_error)

if (n == ngx_error)

刪除結束控制字元*

while (n-- buf[n] == cr ||buf[n] == lf))

將字串轉換為數字以獲取主程序 pid*

pid = ngx_atoi(buf, +n);

封裝終止系統呼叫的信令功能*

return ngx_os_signal_process(cycle, sig, pid);

其次,在獲取到正在執行的 master 程序的 pid 後,呼叫 kill 命令將新的 nginx 程序攜帶的訊號傳送給正在執行的 master 程序,這也是 ngx os 訊號 process() 函式的功能,實現如下:

ngx_int_t

ngx_os_signal_process(ngx_cycle_t *cycle, char *name, ngx_pid_t pid)

ngx_signal_t *sig;

遍歷 nginx 核心支援的訊號,找到與名稱相同的訊號,並通過 kill 系統。

呼叫向主程序傳送訊號。

for (sig = signals; sig->signo != 0; sig++)

ngx_log_error(ngx_log_alert, cycle->log, ngx_errno,"kill(%p, %d) failed", pid, sig->signo);

return 1;

至此,新的nginx程序的任務完成,然後返回退出,那麼接下來執行中的master程序會發生什麼呢?這涉及到主程序的工作迴圈。 我們知道 master 程序並不向外界提供服務,而是專門用來管理 worker 程序的,那麼在 nginx 中是如何實現的呢?

如前所述,nginx 通過啟動乙個新程序向主程序傳送訊號,因此主程序正在等待訊號到達工作迴圈。 訊號到達後,會觸發訊號處理功能,然後檢測訊號的相應標誌位置,然後在主程序中檢測相應的標誌進行相應的處理。 在討論主程序如何處理特定訊號之前,讓我們先看看主程序對哪些訊號感興趣,如下所示:

上面**中的chld訊號不是由新的nginx程序傳送的,但是作業系統核心在檢測到子程序正在退出時,會向父程序(即master)傳送chld訊號,然後master程序會對此進行進一步分析,這就是ngx reap children()的功能。 在 ngx master process cycle() 中,我們可以看到 master 首先將自己感興趣的訊號新增到阻塞自身的訊號集合中(通過 sig 塊呼叫 sigprocmask(),然後在這些操作後呼叫 sigsuspend() 暫停自己,等待訊號集中的訊號發生,喚醒自己, 然後在訊號發生後根據全域性變數(見上表)進行相應的處理,處理流程圖如下:

從主程序的工作迴圈中,我們可以看到,當主程序接收到相應的訊號並完成自己的處理過程時,會通過ngx signal worker processes()向工作程序傳送相應的訊號。 例如,在收到退出訊號後,主站會向所有 worker 子程序傳送退出訊號,通知 worker 優雅退出(所謂優雅,其實就是處理現有連線,不接受新連線),並為監聽器關閉套接字控制代碼。 那麼,工作程序會對哪些訊號感興趣,當它從主程序接收到相應的訊號時會發生什麼呢?這就是工人工作週期的意義所在。 在 worker 程序中,在接收到 master 傳送的訊號後,我們也會看到 worker 對哪些訊號感興趣,並在引入 worker 工作週期之前設定相應的全域性變數,具體如下:

除了上述三個訊號之外,在工作程序的工作迴圈中還可以看到另乙個全域性變數 NGX 激勵。 只有乙個地方會設定此標誌,即在收到退出訊號後。 NGX Quit 只會首次將 NGX Exciting 設定為 1。 為什麼?因為當 worker 收到退出訊號時,它知道它需要優雅地關閉程序,即完成對現有連線的處理並不再接受新連線,NGX Exciting 表示退出狀態,即仍有尚未處理的連線。 以下是工作程序的工作原理:

這裡只是對主程序和工作程序的訊號處理過程的簡要說明,對於詳細的處理過程,如平滑公升級、配置檔案的實時效果等,你還是需要閱讀**才能更好地梳理細節。

相關問題答案

    Docker 01 Nginx 容器部署,建立 docker 容器後修改掛載目錄

    搜尋 nginx 影象。root hongpon docker 映象,檢視當前可用的映象。repository tag image id created size hello world latest caaac months ago .kb tomcat latest fbadc months a...

    Nginx伺服器動態快取機制及效能提公升技術

    NGINX是一款高效能的Web伺服器和反向伺服器,廣泛用於構建高併發 高效能的網路應用。為了進一步提高nginx伺服器的效能,引入了動態快取機制。本文將詳細介紹 NGINX 伺服器的動態快取機制和效能提公升技巧,包括快取策略 快取配置 快取重新整理和失效 快取效能監控等,幫助您充分利用 NGINX ...

    軌道交通訊號與控制研究生方向

    軌道交通訊號與控制是軌道交通系統的重要組成部分,負責列車執行的安全 高效 準確控制。軌道交通訊號與控制專業主要方向如下 .訊號系統 訊號系統是軌道交通訊號控制系統的核心,負責列車 車站 線路等的資訊傳輸 處理和控制。訊號系統的研究內容主要包括 信令系統基礎知識。自動列車控制。自動站控制。自動生產線控...

    如何控制自己的情緒而不被情緒所控制?

    控制情緒是一項重要的心理技能,有助於保持身心健康並改善人際關係。這裡有一些方法可以幫助你控制你的情緒,避免被它們控制。認知重建 學會檢查和調整自己的思維模式。試著以更積極 理性的方式看待事物,避免過於悲觀或消極的想法。情緒識別 學會識別和理解你的情緒。了解您當前的情緒狀態是憤怒 焦慮還是抑鬱可以幫助...

    訊號差 沒有訊號?HUAWEI Mate X5 靈犀通訊技術,讓你隨時線上

    我在地鐵上和同事說話,但我的聲音突然斷斷續續 和家人 在一起,卻因為電梯和地下車庫,畫面卡住了 乘坐高鐵的時候,我和隊友一起開著黑車,卻突然卡住了,失去了機會.你有沒有被這些問題困擾過?雖然隨著城市化程序的推進,在日常生活中卻出現了很少的訊號盲區。然而,由於各種複雜環境和個體因素的影響,絕大多數手機...