日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

nginx平滑升級、nginx支持的kill信號

作者:MssGuo 更新時間: 2022-09-25 編程語言

前言

環境:centos7.9、源碼編譯安裝的nginx

nginx支持的kill信號

我們源碼編譯安裝的nginx,其啟動通過直接執行 /usr/local/nginx/sbin/nginx 來啟動nginx,停止,退出,重開日志,重載配置是通過/usr/local/nginx/sbin/nginx -s stop|quit|reopen|reload來發送信息給master進程實現的。除了這種方式,官方說明文檔顯示還提供kill命令來發送對應的信息給nginx主進程,nginx的master進程接收到這些信號就會執行對應的操作,如下:

kill 命令傳送信號給nginx的master進程,注意是發送給master進程:
TERM、INIT  :強制退出,當前的請求不執行完成就退出 等介于 ./nginx -s stop 
QUIT 		:優雅退出,等待請求執行完成后退出 等介于 ./nginx -s quit
HUP			:重載配置文件,用新的配置文件啟動新的work進程并優雅的關閉舊的work進程,等介于./nginx -s reload
USR1		:重開日志,等價于./nginx -s reopen
USR2		:平滑的升級nginx,拉起一個新的nginx主進程,同時做到不停止舊的nginx主進程
WINCH		:優雅的關閉worker進程,發送一個WINCH信號給master進程,告知其優雅的關閉worker進程(一般不常用)

演示示例:
kill -TERM 195916			#強制停止nginx,等價于 ./nginx -s stop
kill -INT 197019			#強制停止nginx,等價于 ./nginx -s stop 
kill -QUIT 197073			#優雅的退出nginx,等價于 ./nginx -s quit 
kill -HUP 197075			#重載配置文件,等價于 ./nginx -s reload 
kill -USR1 197220			#重開日志,等價于 ./nginx -s reopen 
kill -WINCH 197222			#優雅的關閉worker進程

備注:信號都是發送給nginx的master進程的

先安裝一個nginx-1.18.0舊版本來演示

useradd -s /sbin/nologin -M nginx
yum -y install gcc gcc-c++ make pcre pcre-devel zlib-devel zlib openssl-devel openss
wget http://nginx.org/download/nginx-1.18.0.tar.gz
tar zxvf nginx-1.18.0.tar.gz
cd nginx-1.18.0
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module  --with-http_ssl_modul
make -j 8
make install
cd usr/local/nginx/sbin
./nginx
ps -ef | grep nginx
root      1679     1  0 11:23 ?        00:00:00 nginx: master process ./nginx
nginx     1680  1679  0 11:23 ?        00:00:00 nginx: worker process
nginx     1681  1679  0 11:23 ?        00:00:00 nginx: worker process
#下面開始平滑升級nginx為nginx-1.22.0版本,不停nginx升級,實現平滑升級nginx

方法一、 nginx平滑升級

1、如果我們想要更換nginx版本,升級為更高版本的nginx,無非就是重新編譯安裝新版本的nginx,然后停止舊版本nginx,啟動新版本nginx。這切換期間勢必存在nginx服務不可用。(因為我們不能同時啟動兩個版本的nginx,會存在端口沖突的問題)
2、官網給我們提供了上面問題的解決方案,即平滑升級nginx,所謂平滑升級是指舊的nginx不停止,新的nginx又可以啟動,即同時存在舊的nginx和新的nginx,當舊的nginx請求處理完畢,關閉舊的nginx。這就要用到我們前面所說的 USR2 信號來實現nginx的平滑升級了。

USR2 	平滑啟動nginx進程
WINCH	優雅的停止worker進程
QUIT	優雅的停止舊的master進程	

先查看現在的nginx的版本:

/usr/local/nginx/sbin/nginx -V
ginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module

編譯安裝高版本的nginx,編譯參數要與原來舊版本參數的一致(只多不少),安裝路徑要與原來舊版本安裝路徑一樣;

注意:升級新版本,新版本的安裝路徑要與舊版本的安裝路徑保持一致,安裝完成,會在sbin目錄下存在一個nginx(新版本)、nginx.old(舊版本);

wget http://nginx.org/download/nginx-1.22.0.tar.gz
tar -zxvf nginx-1.22.0.tar.gz
cd nginx-1.22.0
./configure  --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module

make -j 8 && make install 
[root@nginx ~]# cd /usr/local/nginx/sbin					#進入nginx的目錄
[root@nginx sbin]# ll					#查看nginx的可執行文件,可以看到我們現在有兩個nginx的可執行文件
total 11712
-rwxr-xr-x 1 root root 6034160 Sep 23 12:47 nginx		#新版本的nginx-1.22.0
-rwxr-xr-x 1 root root 5952184 Sep 23 11:22 nginx.old	#原來舊版本nginx-1.18.0被備份為nginx.old了
[root@nginx sbin]# ./nginx -V			#查看nginx的版本,確認是新版本的nginx-1.22.0
nginx version: nginx/1.22.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module
[root@nginx sbin]# ./nginx.old -V		#查看nginx的版本,確認是舊版本的nginx-1.18.0
nginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module
[root@nginx sbin]#

這時候直接./nginx 啟動新版本肯定是報錯的,因為端口被占用,我們需要使用 USR2 來平滑升級nginx

#先查看舊版本的nginx的進程
[root@nginx sbin]# ps -ef | grep nginx
root      1679     1  0 11:23 ?        00:00:00 nginx: master process ./nginx	#得到舊版本的nginx的master進程pid
nginx     1851  1679  0 11:25 ?        00:00:00 nginx: worker process
nginx     1852  1679  0 11:25 ?        00:00:00 nginx: worker process
[root@nginx sbin]#

#使用 kill -USR2 舊的主進程號 命令來平滑升級
[root@nginx sbin]# kill -USR2 1679	#向舊版本nginx的master進程發送USR2信號

#再查看nginx的進程,這時就啟動新版本的nginx進程,此時同時存在新舊版本的nginx進程
[root@nginx sbin]# ps -ef | grep nginx
root      1679     1  0 11:23 ?        00:00:00 nginx: master process ./nginx	#這是舊版本的nginx/1.18.0
nginx     1851  1679  0 11:25 ?        00:00:00 nginx: worker process			#這是舊版本的nginx/1.18.0
nginx     1852  1679  0 11:25 ?        00:00:00 nginx: worker process			#這是舊版本的nginx/1.18.0

root      9336  1679  0 12:55 ?        00:00:00 nginx: master process ./nginx	#這是新版本的nginx/1.22.0
nginx     9337  9336  0 12:55 ?        00:00:00 nginx: worker process			#這是新版本的nginx/1.22.0
nginx     9338  9336  0 12:55 ?        00:00:00 nginx: worker process			#這是新版本的nginx/1.22.0

#先使用 kill -WINCH 舊的主進程號 命令優雅的關閉舊版本的worker進程
[root@nginx sbin]# kill -WINCH 1679		#向舊版本nginx的master進程發送WINCH信號,告知其優雅的停止worker進程

#確認nginx升級沒有問題了,再使用命令 kill -QUIT	 舊的主進程號 優雅的關閉舊版本的nginx master進程
[root@nginx sbin]# kill -QUIT 1679		#向舊版本nginx的master進程發送QUIT信號,告知其優雅的退出

#至此,此時已經完成了nginx版本的平滑升級

方法二、 nginx平滑升級

編譯安裝高版本的nginx:

wget http://nginx.org/download/nginx-1.22.0.tar.gz
tar -zxvf nginx-1.22.0.tar.gz
./configure  --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module

#預編譯完成后會得到一個Makefile 文件,我們來看下這個文件的內容,如下:
[root@nginx nginx-1.22.0]# cat Makefile 

default:	build

clean:
	rm -rf Makefile objs

.PHONY:	default clean

build:
	$(MAKE) -f objs/Makefile

install:
	$(MAKE) -f objs/Makefile install

modules:
	$(MAKE) -f objs/Makefile modules

upgrade:
	/usr/local/nginx/sbin/nginx -t

	kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`				#平滑升級
	sleep 1
	test -f /usr/local/nginx/logs/nginx.pid.oldbin

	kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`			#優雅的關閉舊版本的nginx

.PHONY:	build install modules upgrade
[root@nginx nginx-1.22.0]# 

#如上看到的,make 命令有個參數upgrade,這個參數就是平滑升級的,看起內容我看應該可以看到,其平滑升級的原理仍然是我們前面方法一的說的,先發送 USR2 信號給舊的nginx master進程告知其平滑升級,拉起新版本的nginx進程,然后再發送QUIT信號給舊版本的master進程,優雅的關閉舊版本的nginx。

make install  &&  make upgrade  #直接平滑升級,
[root@nginx sbin]# ll
total 11712
-rwxr-xr-x 1 root root 6034160 Sep 23 17:36 nginx				#新版本的nginx
-rwxr-xr-x 1 root root 5952184 Sep 23 17:27 nginx.old			#就版本的nginx
[root@nginx sbin]# 
[root@nginx sbin]# ps -ef | grep nginx							#現在只有新版本的nginx
root     31946     1  0 17:36 ?        00:00:00 nginx: master process ./nginx
nginx    31947 31946  0 17:36 ?        00:00:00 nginx: worker process
root     32137 15942  0 17:40 pts/4    00:00:00 grep --color=auto nginx
[root@nginx sbin]#
#再次,平滑升級完成

方法三、 nginx平滑升級(保守方法)

同理,解壓編譯新版本的nginx,但此時的安裝路徑安裝在一個全新的目錄,不再與原來舊版本的安裝路徑一樣。

wget http://nginx.org/download/nginx-1.22.0.tar.gz
tar -zxvf nginx-1.22.0.tar.gz
./configure  --prefix=/usr/local/nginx2 --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module
make -j 8 && make install 											#安裝全新版本的nginx
mv /usr/local/nginx/sbin/nginx  /usr/local/nginx/sbin/nginx.old		#備份原來的舊版本的nginx,備份不影響正在運行的nginx進程
cp /usr/local/nginx2/sbin/nginx /usr/local/nginx/sbin/ 				#將新版本的nginx可執行文件復制到舊版本的安裝路徑下

#同理,下面的步驟仍然是發送信號SER2給舊版本的nginx的master進程進行平滑升級nginx,然后再關閉舊版本的worker進程和master進程

[root@nginx sbin]# kill -USR2 1679		#向舊版本nginx的master進程發送USR2信號
#先使用 kill -WINCH 舊的主進程號 命令優雅的關閉舊版本的worker進程
[root@nginx sbin]# kill -WINCH 1679		#向舊版本nginx的master進程發送WINCH信號,告知其優雅的停止worker進程
#確認nginx升級沒有問題了,再使用命令 kill -QUIT	 舊的主進程號 優雅的關閉舊版本的nginx master進程
[root@nginx sbin]# kill -QUIT 1679		#向舊版本nginx的master進程發送QUIT信號,告知其優雅的退出

#至此,此時已經完成了nginx版本的平滑升級 

nginx版本回退

如果在使用新版本的nginx過程中發現新版本存在問題,那么可以進行nginx版本回退,回退到舊版本的nginx,。
版本回退可以分2中情況,如下:
1、事前對舊版本nginx進行備份,若出現問題,直接將舊版本重新拷貝會/usr/local目錄下,重啟nginx舊版本操作,執行如下:

#停止nginx服務進行版本回退
killall nginx
cp /usr/local/nginx-1.18.0.bak  /usr/local/nginx
/usr/local/nginx/sbin/nginx
#檢查nginx狀態
ps -ef |grep nginx

2、在新版本nginx的master進程和舊版本的master進程同時存在時,即只關閉了舊版本的worker進程沒有關閉舊版本的master進程的情況下,可以這樣回滾,如下:

#向舊版本的master進程發送HUP信號,重載配置,會重新拉起新的worker進程
kill -HUP 舊masterPID				# HUP是重載配置,會重新啟動worker進程

#關閉新版本nginx的master進程,并將原sbin目錄下的nginx.old(舊版本nginx二進制文件)重新改回nginx,以便管理nginx
kill -WINCH 新master的PID				#優雅額關閉新版本的worker進程
kill -QUIT 新master的PID				#優雅額關閉新版本的matser進程
cd /usr/local/nginx/sbin/
mv nginx nginx_1.22.0_bak				#先備份新版本的nginx可執行文件
mv nginx.old nginx						#將舊版本的nginx可執行文件恢復回來

總結

nginx支持的kill發送以下的信號:

kill -TERM 195916			#強制停止nginx,等價于 ./nginx -s stop
kill -INT 197019			#強制停止nginx,等價于 ./nginx -s stop 
kill -QUIT 197073			#優雅的退出nginx,等價于 ./nginx -s quit 
kill -HUP 197075			#重載配置文件,等價于 ./nginx -s reload 
kill -USR1 197220			#重開日志,等價于 ./nginx -s reopen 
kill -USR2 197220			#平滑升級nginx
kill -WINCH 197222			#優雅的關閉worker進程
備注:信號都是發送給nginx的master進程的

平滑升級nginx的大概思路:

方法一、
1、編譯安裝高版本的nginx,其./configure預編譯的參數要與原來舊版本的參數一致,包括安裝路徑也要一致;
2、make -j 10 && make install 編譯安裝;
3、安裝完成之后,在/usr/local/nginx/sbin/目錄下就會存在一個可執行文件,nginx、nginx.old,前者是新版本的可執行文件,后者是舊版本的可執行文件;
4、使用 kill -USR2 舊版本的masterPID   命令進行平滑升級,此時就會同時存在新版本舊版本的nginx進程;
5、使用 kill -WINCH 舊版本的masterPID  命令優雅的關閉舊版本的worker進程
6、確認新版本的nginx進程沒有問題后,此時可以使用 kill -QUIT 舊版本的masterPID  命令優雅的關閉舊版本的master進程;
7、nginx升級已完成。
方法二、
1、編譯安裝高版本的nginx,其./configure預編譯的參數要與原來舊版本的參數一致,包括安裝路徑也要一致;
2、make install && make upgrade  編譯安裝,make upgrade直接平滑升級;
3、安裝完成之后,在/usr/local/nginx/sbin/目錄下就會存在一個可執行文件,nginx、nginx.old,前者是新版本的可執行文件,后者是舊版本的可執行文件;
4、此時平滑升級完成了,ps -ef  | grep nginx 查看只會有新版本的nginx,因為當你執行make upgrade的時候,其實已經發送了kill -QUIT 信號給舊版本的nginx,所以舊版本的nginx進程已經優雅的退出了。
5、nginx升級已完成。
方法三、(保守方法)
1、解壓編譯新版本的nginx,但此時的安裝路徑安裝在一個全新的目錄,不再與原來舊版本的安裝路徑一樣;
2、備份舊版本的可行性文件,復制新版本的nginx的可執行文件
mv /usr/local/nginx/sbin/nginx  /usr/local/nginx/sbin/nginx.old		#備份原來的舊版本的nginx,備份不影響正在運行的nginx進程
cp /usr/local/nginx2/sbin/nginx /usr/local/nginx/sbin/ 				#將新版本的nginx可執行文件復制到舊版本的安裝路徑下
3、使用 kill -USR2 舊版本的masterPID   命令進行平滑升級,此時就會同時存在新版本舊版本的nginx進程;
4、使用 kill -WINCH 舊版本的masterPID  命令優雅的關閉舊版本的worker進程
5、確認新版本的nginx進程沒有問題后,此時可以使用 kill -QUIT 舊版本的masterPID  命令優雅的關閉舊版本的master進程;
6、nginx升級已完成。

版本回退:
1、如果事前對舊版本nginx進行備份,若出現問題,直接將舊版本重新拷貝會/usr/local目錄下,重啟nginx舊版本操作,執行如下:

#停止nginx服務進行版本回退
killall nginx
cp /usr/local/nginx-1.18.0.bak  /usr/local/nginx
/usr/local/nginx/sbin/nginx
#檢查nginx狀態
ps -ef |grep nginx

2、在新版本nginx的master進程和舊版本的master進程同時存在時,即只關閉了舊版本的worker進程沒有關閉舊版本的master進程的情況下,可以這樣回滾,如下:

#向舊版本的master進程發送HUP信號,重載配置,會重新拉起新的worker進程
kill -HUP 舊masterPID				# HUP是重載配置,會重新啟動worker進程

#關閉新版本nginx的master進程,并將原sbin目錄下的nginx.old(舊版本nginx二進制文件)重新改回nginx,以便管理nginx
kill -WINCH 新master的PID				#優雅額關閉新版本的worker進程
kill -QUIT 新master的PID				#優雅額關閉新版本的matser進程
cd /usr/local/nginx/sbin/
mv nginx nginx_1.22.0_bak				#先備份新版本的nginx可執行文件
mv nginx.old nginx						#將舊版本的nginx可執行文件恢復回來

原文鏈接:https://blog.csdn.net/MssGuo/article/details/127002480

欄目分類
最近更新