前言
环境: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
kill -INT 197019
kill -QUIT 197073
kill -HUP 197075
kill -USR1 197220
kill -WINCH 197222
备注:信号都是发送给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平滑升级
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 ~]
[root@nginx sbin]
total 11712
-rwxr-xr-x 1 root root 6034160 Sep 23 12:47 nginx
-rwxr-xr-x 1 root root 5952184 Sep 23 11:22 nginx.old
[root@nginx sbin]
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 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
[root@nginx sbin]
root 1679 1 0 11:23 ? 00:00:00 nginx: master process ./nginx
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]
[root@nginx sbin]
[root@nginx sbin]
root 1679 1 0 11:23 ? 00:00:00 nginx: master process ./nginx
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 9336 1679 0 12:55 ? 00:00:00 nginx: master process ./nginx
nginx 9337 9336 0 12:55 ? 00:00:00 nginx: worker process
nginx 9338 9336 0 12:55 ? 00:00:00 nginx: worker process
[root@nginx sbin]
[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/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module
[root@nginx nginx-1.22.0]
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`
.PHONY: build install modules upgrade
[root@nginx nginx-1.22.0]
make install && make upgrade
[root@nginx sbin]
total 11712
-rwxr-xr-x 1 root root 6034160 Sep 23 17:36 nginx
-rwxr-xr-x 1 root root 5952184 Sep 23 17:27 nginx.old
[root@nginx sbin]
[root@nginx sbin]
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
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old
cp /usr/local/nginx2/sbin/nginx /usr/local/nginx/sbin/
[root@nginx sbin]
[root@nginx sbin]
[root@nginx sbin]
nginx版本回退
如果在使用新版本的nginx过程中发现新版本存在问题,那么可以进行nginx版本回退,回退到旧版本的nginx,。 版本回退可以分2中情况,如下: 1、事前对旧版本nginx进行备份,若出现问题,直接将旧版本重新拷贝会/usr/local目录下,重启nginx旧版本操作,执行如下:
killall nginx
cp /usr/local/nginx-1.18.0.bak /usr/local/nginx
/usr/local/nginx/sbin/nginx
ps -ef |grep nginx
2、在新版本nginx的master进程和旧版本的master进程同时存在时,即只关闭了旧版本的worker进程没有关闭旧版本的master进程的情况下,可以这样回滚,如下:
kill -HUP 旧masterPID
kill -WINCH 新master的PID
kill -QUIT 新master的PID
cd /usr/local/nginx/sbin/
mv nginx nginx_1.22.0_bak
mv nginx.old nginx
总结
nginx支持的kill发送以下的信号:
kill -TERM 195916
kill -INT 197019
kill -QUIT 197073
kill -HUP 197075
kill -USR1 197220
kill -USR2 197220
kill -WINCH 197222
备注:信号都是发送给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
cp /usr/local/nginx2/sbin/nginx /usr/local/nginx/sbin/
3、使用 kill -USR2 旧版本的masterPID 命令进行平滑升级,此时就会同时存在新版本旧版本的nginx进程;
4、使用 kill -WINCH 旧版本的masterPID 命令优雅的关闭旧版本的worker进程
5、确认新版本的nginx进程没有问题后,此时可以使用 kill -QUIT 旧版本的masterPID 命令优雅的关闭旧版本的master进程;
6、nginx升级已完成。
版本回退: 1、如果事前对旧版本nginx进行备份,若出现问题,直接将旧版本重新拷贝会/usr/local目录下,重启nginx旧版本操作,执行如下:
killall nginx
cp /usr/local/nginx-1.18.0.bak /usr/local/nginx
/usr/local/nginx/sbin/nginx
ps -ef |grep nginx
2、在新版本nginx的master进程和旧版本的master进程同时存在时,即只关闭了旧版本的worker进程没有关闭旧版本的master进程的情况下,可以这样回滚,如下:
kill -HUP 旧masterPID
kill -WINCH 新master的PID
kill -QUIT 新master的PID
cd /usr/local/nginx/sbin/
mv nginx nginx_1.22.0_bak
mv nginx.old nginx
|