本篇文章給大家分享的是有關Nginx中進程管理和重載的原理是什么,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
Nginx是多進程結構,多進程結構設計是為了保證Nginx的高可用高可靠,包含:
master進程:父進程,負責worker進程的管理
worker進程:子進程,worker進程一般配置與服務器CPU核數相同,worker進程用來處理具體請求。
cache進程:也是子進程,包括cache manager和cache loader進程,主要是反向代理做緩存使用。
注:多進程相對于多線程之所以能夠保證高可用與高可靠是因為進程間地址空間是獨立的,進程間的任務不會相互影響,相對多線程更加耗費CPU資源。而多線程共享一個進程的地址空間,其中一個線程任務失敗會影響到其它線程任務。
假設我們的Nginx服務的用戶是nginx,我們可以使用如下命令查看當前運行的Nginx服務的master進程和worker進程,而且可以看到4個worker進程的父進程ID都是master的進程ID(1325)。
[root@master ~]# ps -ef | grep nginx | grep -v grep | grep -v php-fpm root 1325 1 0 11:28 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx nginx 1332 1325 0 11:28 ? 00:00:00 nginx: worker process nginx 1334 1325 0 11:28 ? 00:00:00 nginx: worker process nginx 1335 1325 0 11:28 ? 00:00:00 nginx: worker process nginx 1336 1325 0 11:28 ? 00:00:00 nginx: worker process
我們可以通過 lsof -i:nginx端口號
來查看我們的master和worker進程。
[root@master ~]# lsof -i:80 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nginx 1325 root 6u IPv4 22282 0t0 TCP *:http (LISTEN) nginx 1332 nginx 6u IPv4 22282 0t0 TCP *:http (LISTEN) nginx 1334 nginx 6u IPv4 22282 0t0 TCP *:http (LISTEN) nginx 1335 nginx 6u IPv4 22282 0t0 TCP *:http (LISTEN) nginx 1336 nginx 6u IPv4 22282 0t0 TCP *:http (LISTEN)
Linux的信號量管理機制
信號是進程間通信方式之一,典型用法是:終端用戶輸入中斷命令,通過信號機制停止一個程序的運行。
我們可以通過給進程發送信號來管理我們的進程,kill -l
命令可以查看linux支持的信號量
一共有64號信號量,主要需要弄清如下幾個:
kill -1 $PID:(SIGHUP)重新加載進程,對于與終端脫離關系的守護進程,這個信號用于通知它重新讀取配置文件;
kill -2 $PID:(SIGINT)中斷(通Ctrl+C);
kill -3 $PID:(SIGQUIT)從鍵盤輸入的退出(ctrl-\);
kill -9 $PID:(SIGKILL)立即殺死進程,無論當前程序處于什么狀態;
kill -10 $PID:(SIGUSR1)$USR1和$USR2都是留給用戶自定義的信號量;
kill -12 $PID:($IGUSR2)
kill -15 $PID:(SIGTERM)正常停止一個進程;
kill -17 $PID:(SIGCHLD)父子進程通信的信號量,父進程可以fork()出很多子進程,子進程掛掉會給父進程發送信號;
kill 可將指定的信息送至程序。預設的信息為 SIGTERM(15),可將指定程序終止。若仍無法終止該程序,可使用 SIGKILL(9) 信息嘗試強制刪除程序。程序或工作的編號可利用 ps 指令或 jobs 指令查看。
kill -l # 查看所有能夠支持的信號 kill PID # 殺死一個進程 kill 1024 # 殺死多個進程 進程號之間用空格隔開 kill 1024 2048 # kill -9 表示立即強制結束進程 kill -9 1024
注:Ctrl+C:停止終端中正在運行的進程,Ctrl+C可以比較有好地中止終端中正在運行的程序(進程)
利用信號量管理Nginx進程
管理Nginx進程可以這些方式:master進程
、worker進程
、命令行
使用信號量管理master和worker(不推薦使用發送信號量的方式來管理worker進程,worker進程應該交給master進程來管理和維護)。
Master進程
監控worker進程
CHLD
管理worker進程
接收信號
TERM、INT
QUIT
HUP
USR1
USR2
WINCH
示例:
通過kill命令殺死master進程
kill -s SIGTERM 1325
通過kill命令讓Nginx重新讀取文件,這樣會關閉就得worker進程,生成新的worker進程,master進程(ID)依舊保持不變
kill -s SIGHUP 1325
Worker進程
接收信號
TERM、INT
QUIT
USR1
WINCH
雖然可以,但是不推薦使用信號量方式直接管理worker進程,worker進程應該交給master進程來管理和維護
示例:
使用kill命令殺死一個worker進程,這樣會殺死一個worker進程,linux會殺掉的worker進程的父進程(master進程)發送SIGCHLD信號量,所以master進程監測到我們某一個子進程可能出了問題,會啟動一個新的worker進程,維護worker進程的數量。
kill -s SIGTERM 1332
命令行
reload:HUP
reopen:USR2
stop:TERM
quit:QUIT
可以使用nginx -h
查看幫助命令
[itbsl@master ~]$ nginx -h nginx version: nginx/1.18.0 Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives] Options: -?,-h : this help -v : show version and exit -V : show version and configure options then exit -t : test configuration and exit -T : test configuration, dump it and exit -q : suppress non-error messages during configuration testing -s signal : send signal to a master process: stop, quit, reopen, reload -p prefix : set prefix path (default: /usr/local/nginx-1.18.0/) -c filename : set configuration file (default: conf/nginx.conf) -g directives : set global directives out of configuration file
參數說明:
-?,-h:查看幫助
-v:查看Nginx版本
-V:查看Nginx版本和編譯選項
-t:檢查配置文件語法是否正確
-T:檢查配置文件語法是否正確,并打印
-q:在檢查配置文件時不顯示非錯誤消息
-s:給master進程發送信號,可以發送:stop、quit、reopen、reload
-c:指定配置文件
-g:設置配置文件之外的全局指令
我們知道了可以通過給nginx的master進程發送SIGHUP信號,或者使用nginx -s reload
命令來達到重新載入配置文件,從而使nginx平滑升級。那我們執行這樣一個命令之后,對nginx本身來說背后發生了什么事情呢,它是如何保證新老請求如何平滑過渡的?
reload重載配置文件的流程
向master進程發送HUP信號(reload命令)
master進程檢查配置語法是否正確
master進程打開監聽端口(在修改配置文件的端口情況下,可能)
master進程使用新的配置文件啟動新的worker子進程
master進程向老的worker子進程發送QUIT信號
舊的worker進程關閉監聽句柄,處理完當前連接后關閉進程
如果用圖示來描述的話大概如下圖所示
圖示解析:
1.左邊綠色的狀態是執行nginx -s reload
命令之前的狀態,按照我個人主機的配置時一個master進程和4個worker子進程。
2.為了模擬執行nginx -s reload
命令后原來的worker進程會處理完請求后再被殺掉,我模擬一個需要很久才能處理完任務并響應的接口,是的,我在代碼里sleep 15秒,也就是說這個接口響應需要15秒,時間弄長點方便我們來觀察中間態,注意,在執行reload命令前請求該接口
<?php sleep(15); echo json_encode(['msg' => 'hello world']);die();
3.我們已經知道了master進程會把任務交給worker子進程處理,目前只有一個任務,所以當前只需要一個worker進程需要處理任務。
4.執行reload命令,master進程會創建4個(與你配置有關)新的worker進程(我上圖中的黃色worker進程),關閉掉舊的空閑worker進程(綠色worker進程),而正在處理請求的舊worker進程不會立即關閉,而是會等請求處理完畢就關閉。
5.剩下的最后一個舊worker進程任務處理完畢也被關掉,最后剩下的都是使用新nginx.conf配置產生的新worker進程,可以看下面的這張圖,那個處于is shutting down的舊worker進程就是因為處理上面sleep 15秒的任務接口還沒處理完畢,所以依然能夠被看到。
以上就是Nginx中進程管理和重載的原理是什么,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。