nginx平滑升级、nginx支持的kill信号

前言

环境: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主进程,nginxmaster进程接收到这些信号就会执行对应的操作,如下:

kill 命令传送信号给nginx的master进程,注意是发送给master进程,不是worker进程:
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进程(等连接基本处理完毕了在关闭旧的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。

[root@nginx sbin]#  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平滑升级(保守方法)

同理,解压编译新版本的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信号,让其拉起新版本的nginx

#先使用 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、在新版本nginxmaster进程和旧版本的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可执行文件恢复回来
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值