在线不停机升级Nginx图解
Nginx升级1.6----->1.7
(1)查看一下我的老版本的nginx的版本信息和模块信息,因为升级要把老版本的模块信息也需要编译进去
[root@www nginx-1.17.9]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.16.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
configure arguments: --prefix=/usr/local/nginx
(2)先来备份一下旧版本的nginx的二进制文件
[root@www src]# cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old
(3)编译nginx1.17版本,注意这里只需要make,不用多此一举make install,因为我们只需要编译好的新版本的nginx二进制文件
[root@www src]# cd /usr/src/nginx-1.17.9
[root@www nginx-1.17.9]# ./configure --prefix=/usr/local/nginx
[root@www nginx-1.17.9]# make
[root@www nginx-1.17.9]# ls objs/ --这个我们编译好的最新版本的nginx的二进制文件
autoconf.err Makefile nginx nginx.8 ngx_auto_config.h ngx_auto_headers.h ngx_modules.c ngx_modules.o src
(4)复制新版本Nginx1.17二进制文件到现有Nginx工作目录
将编译好最新版本的nginx二进制文件替换正在运行nginx进程所使用的二进制文件,在大部分场景下面,新编译的nginx二进制文件所指定的配置选项,比如配置文件的目录在哪里,日志文件目录在哪里,必须保持和老的nginx是一致的,否则会导致无法复用nginx配置文件。所以在替换的时候注意备份,在Linux当中,当你正在覆盖一个正在使用的文件时候加上-f,即cp -f才能替换掉。
把新版本的nginx二进制文件覆盖老文件,这样,运行中的master进程生成子进程后才能载入新版本的nginx。注意,虽然你覆盖了老nginx,但并不会影响运行中的老nginx进程。
[root@www nginx-1.17.9]# cp -f objs/nginx /usr/local/nginx/sbin/nginx
cp: overwrite ?.usr/local/nginx/sbin/nginx?. y
[root@www nginx-1.17.9]# ll /usr/local/nginx/sbin/
-rwxr-xr-x 1 root root 3849136 Mar 18 22:07 nginx --这个是最新版本的nginx的二进制文件
-rwxr-xr-x 1 root root 3825496 Mar 18 21:56 nginx.old --这个是旧版本的nginx的配置文件
(5)给当前的Nginx发送USR2信号(这个时候新的master进程使用是新的nginx二进制文件启动的)
给正在运行nginx的master进程发送一个信号,告诉master我们要热部署了,做一次版本升级,这个信号是USR2,USR2这个信号就是来传递热部署的信号
[root@www nginx-1.17.9]# ps -ef | grep nginx
root 55384 1 0 19:02 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 63376 55384 0 21:24 ? 00:00:00 nginx: worker process
[root@www nginx-1.17.9]# kill -USR2 55384
[root@www nginx-1.17.9]# ps -ef | grep nginx --可以看到老的master进程新启动了一个新的master进程,这个新的master进程使用了我们刚刚复制过来的最新版的nginx二进制文件,老的worker也在运行,新的master会新生成新的worker,老的worker会平滑的将所有请求过渡到新的worker。老的worker不会监听80这种端口了,新的请求和连接会进入到新的nginx进程当中
root 55384 1 0 19:02 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 63376 55384 0 21:24 ? 00:00:00 nginx: worker process
root 68250 55384 0 22:12 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 68251 68250 0 22:12 ? 00:00:00 nginx: worker process
[root@www ~]# ll /usr/local/nginx/logs/
total 16
-rw-r--r-- 1 root root 1678 Mar 17 22:21 access.log
-rw-r--r-- 1 root root 1396 Jun 28 10:39 error.log
-rw-r--r-- 1 root root 5 Jun 28 10:39 nginx.pid #新的master进程
-rw-r--r-- 1 root root 5 Jun 28 10:31 nginx.pid.oldbin #老的master进程
换句话总结就是:
此时Nginx会新开启一个master进程,这个master进程会生成新的worker进程,这就是升级后的Nginx进程,此时老的进程不会自动退出,但是当接收到新的请求不作处理而是交给新的进程处理。
(6)升级成功,停止旧的worker进程和master进程
向老的master进程发送信号WINCH信号,告诉它优雅的关闭其worker进程
[root@www nginx-1.17.9]# kill -WINCH 55384
[root@www nginx-1.17.9]# ps -ef | grep nginx --可以看到老的worker进程已经退出了,老的master进程还在,这就说明所有的请求已经切换到新升级好的nginx中了
root 55384 1 0 19:02 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
root 68250 55384 0 22:12 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 68251 68250 0 22:12 ? 00:00:00 nginx: worker process
kill -QUIT old_master_PID
[root@www nginx-1.17.9]# /usr/local/nginx/sbin/nginx -V --可以看到升级到新的版本了
nginx version: nginx/1.17.9
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
configure arguments: --prefix=/usr/local/nginx
注:如果在版本升级完成后,没有任何问题,需要关闭老的master进程的话,可以使用下面的命令:
kill -QUIT old_master_PID
(6)升级过程中出现问题,回退到老版本
之前旧版本的主进程不要kill关闭,以防万一升级失败还可以进行回滚,向老的master进程发送命令,再将新版本关掉。所以第五步的老的master进程是不会自动退出的,保留着,允许我们做版本的回退
[root@www nginx-1.17.9]# cp -f /usr/local/nginx/sbin/nginx.old /usr/local/nginx/sbin/nginx
--将备份好的旧版本的脚本还原
cp: overwrite ?.usr/local/nginx/sbin/nginx?. y
[root@www nginx-1.17.9]# kill -HUP 55384 -- 重新拉起老的worker进程(唤醒旧版本的master进程,使之产生新的worker进程)
[root@www nginx-1.17.9]# ps -ef | grep nginx
root 55384 1 0 19:02 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
root 68250 55384 0 22:12 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 68251 68250 0 22:12 ? 00:00:00 nginx: worker process
nginx 69435 55384 0 22:36 ? 00:00:00 nginx: worker process
[root@www nginx-1.17.9]# kill -WINCH 68250 --关闭新版本的worker进程
[root@www nginx-1.17.9]# ps -ef | grep nginx
root 55384 1 0 19:02 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
root 68250 55384 0 22:12 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 69435 55384 0 22:36 ? 00:00:00 nginx: worker process
[root@www ~]# kill -QUIT 68250 --关闭新版本的master进程
[root@www ~]# ps -ef | grep nginx
root 55384 1 0 17:05 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 69435 55384 0 20:40 ? 00:00:00 nginx: worker process
至此回退完成!