Nginx是多進(jìn)程結構,多進(jìn)程結構設計是為了保證Nginx的高可用高可靠,包含:
注:多進(jìn)程相對于多線(xiàn)程之所以能夠保證高可用與高可靠是因為進(jìn)程間地址空間是獨立的,進(jìn)程間的任務(wù)不會(huì )相互影響,相對多線(xiàn)程更加耗費CPU資源。而多線(xiàn)程共享一個(gè)進(jìn)程的地址空間,其中一個(gè)線(xiàn)程任務(wù)失敗會(huì )影響到其它線(xiàn)程任務(wù)。
假設我們的Nginx服務(wù)的用戶(hù)是nginx,我們可以使用如下命令查看當前運行的Nginx服務(wù)的master進(jìn)程和worker進(jìn)程,而且可以看到4個(gè)worker進(jìn)程的父進(jìn)程ID都是master的進(jìn)程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
我們可以通過(guò) lsof -i:nginx端口號
來(lái)查看我們的master和worker進(jìn)程。
[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的信號量管理機制
信號是進(jìn)程間通信方式之一,典型用法是:終端用戶(hù)輸入中斷命令,通過(guò)信號機制停止一個(gè)程序的運行。
我們可以通過(guò)給進(jìn)程發(fā)送信號來(lái)管理我們的進(jìn)程,kill -l
命令可以查看linux支持的信號量
一共有64號信號量,主要需要弄清如下幾個(gè):
kill -1 $PID:(SIGHUP)重新加載進(jìn)程,對于與終端脫離關(guān)系的守護進(jìn)程,這個(gè)信號用于通知它重新讀取配置文件;
kill -2 $PID:(SIGINT)中斷(通Ctrl+C);
kill -3 $PID:(SIGQUIT)從鍵盤(pán)輸入的退出(ctrl-\);
kill -9 $PID:(SIGKILL)立即殺死進(jìn)程,無(wú)論當前程序處于什么狀態(tài);
kill -10 $PID:(SIGUSR1)$USR1和$USR2都是留給用戶(hù)自定義的信號量;
kill -12 $PID:($IGUSR2)
kill -15 $PID:(SIGTERM)正常停止一個(gè)進(jìn)程;
kill -17 $PID:(SIGCHLD)父子進(jìn)程通信的信號量,父進(jìn)程可以fork()出很多子進(jìn)程,子進(jìn)程掛掉會(huì )給父進(jìn)程發(fā)送信號;
kill 可將指定的信息送至程序。預設的信息為 SIGTERM(15),可將指定程序終止。若仍無(wú)法終止該程序,可使用 SIGKILL(9) 信息嘗試強制刪除程序。程序或工作的編號可利用 ps 指令或 jobs 指令查看。
kill -l # 查看所有能夠支持的信號 kill PID # 殺死一個(gè)進(jìn)程 kill 1024 # 殺死多個(gè)進(jìn)程 進(jìn)程號之間用空格隔開(kāi) kill 1024 2048 # kill -9 表示立即強制結束進(jìn)程 kill -9 1024
注:Ctrl+C:停止終端中正在運行的進(jìn)程,Ctrl+C可以比較有好地中止終端中正在運行的程序(進(jìn)程)
利用信號量管理Nginx進(jìn)程
管理Nginx進(jìn)程可以這些方式:master進(jìn)程
、worker進(jìn)程
、命令行
使用信號量管理master和worker(不推薦使用發(fā)送信號量的方式來(lái)管理worker進(jìn)程,worker進(jìn)程應該交給master進(jìn)程來(lái)管理和維護)。
Master進(jìn)程
監控worker進(jìn)程
管理worker進(jìn)程
接收信號
示例:
通過(guò)kill命令殺死master進(jìn)程
kill -s SIGTERM 1325
通過(guò)kill命令讓Nginx重新讀取文件,這樣會(huì )關(guān)閉就得worker進(jìn)程,生成新的worker進(jìn)程,master進(jìn)程(ID)依舊保持不變
kill -s SIGHUP 1325
Worker進(jìn)程
接收信號
雖然可以,但是不推薦使用信號量方式直接管理worker進(jìn)程,worker進(jìn)程應該交給master進(jìn)程來(lái)管理和維護
示例:
使用kill命令殺死一個(gè)worker進(jìn)程,這樣會(huì )殺死一個(gè)worker進(jìn)程,linux會(huì )殺掉的worker進(jìn)程的父進(jìn)程(master進(jìn)程)發(fā)送SIGCHLD信號量,所以master進(jìn)程監測到我們某一個(gè)子進(jìn)程可能出了問(wèn)題,會(huì )啟動(dòng)一個(gè)新的worker進(jìn)程,維護worker進(jìn)程的數量。
kill -s SIGTERM 1332
命令行
可以使用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
參數說(shuō)明:
我們知道了可以通過(guò)給nginx的master進(jìn)程發(fā)送SIGHUP信號,或者使用nginx -s reload
命令來(lái)達到重新載入配置文件,從而使nginx平滑升級。那我們執行這樣一個(gè)命令之后,對nginx本身來(lái)說(shuō)背后發(fā)生了什么事情呢,它是如何保證新老請求如何平滑過(guò)渡的?
reload重載配置文件的流程
如果用圖示來(lái)描述的話(huà)大概如下圖所示
圖示解析:
1.左邊綠色的狀態(tài)是執行nginx -s reload
命令之前的狀態(tài),按照我個(gè)人主機的配置時(shí)一個(gè)master進(jìn)程和4個(gè)worker子進(jìn)程。
2.為了模擬執行nginx -s reload
命令后原來(lái)的worker進(jìn)程會(huì )處理完請求后再被殺掉,我模擬一個(gè)需要很久才能處理完任務(wù)并響應的接口,是的,我在代碼里sleep 15秒,也就是說(shuō)這個(gè)接口響應需要15秒,時(shí)間弄長(cháng)點(diǎn)方便我們來(lái)觀(guān)察中間態(tài),注意,在執行reload命令前請求該接口
<?php sleep(15); echo json_encode(['msg' => 'hello world']);die();
3.我們已經(jīng)知道了master進(jìn)程會(huì )把任務(wù)交給worker子進(jìn)程處理,目前只有一個(gè)任務(wù),所以當前只需要一個(gè)worker進(jìn)程需要處理任務(wù)。
4.執行reload命令,master進(jìn)程會(huì )創(chuàng )建4個(gè)(與你配置有關(guān))新的worker進(jìn)程(我上圖中的黃色worker進(jìn)程),關(guān)閉掉舊的空閑worker進(jìn)程(綠色worker進(jìn)程),而正在處理請求的舊worker進(jìn)程不會(huì )立即關(guān)閉,而是會(huì )等請求處理完畢就關(guān)閉。
5.剩下的最后一個(gè)舊worker進(jìn)程任務(wù)處理完畢也被關(guān)掉,最后剩下的都是使用新nginx.conf配置產(chǎn)生的新worker進(jìn)程,可以看下面的這張圖,那個(gè)處于is shutting down的舊worker進(jìn)程就是因為處理上面sleep 15秒的任務(wù)接口還沒(méi)處理完畢,所以依然能夠被看到。
到此這篇關(guān)于Nginx進(jìn)程管理和重載原理的文章就介紹到這了,更多相關(guān)Nginx進(jìn)程管理和重載原理內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。
Copyright ? 2009-2022 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 特網(wǎng)科技 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 百度云 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站