在实际生产环境中,nginx必须一直处于开启状态,所以版本升级也一定要在线更新,也就是热部署。
这个实验就是实现在线进行nginx-1.14.2到nginx-1.15.7的平滑升级,以及出现问题时及时回退。
基本思想:
1、 在不停掉老进程的情况下,启动新进程。
2、 老进程负责处理仍然没有处理完的请求,但不再接受处理请求。
3、 新进程接受新请求。
4、 老进程处理完所有请求,关闭所有连接后,停止
一、实验环境(rhel7.3版本)
selinux和firewalld状态都是disabled
172.25.60.1是实验主机
二、从nginx-1.14.2到nginx-1.15.7的平滑升级
1、下载nginx-1.14.2和nginx-1.15.7的安装包
[root@server1 ~]# ls
nginx-1.14.2.tar.gz nginx-1.15.7.tar.gz
2、安装 nginx-1.14.2
(1)、解压安装包
[root@server1 ~]# tar zxf nginx-1.14.2.tar.gz
[root@server1 ~]# ls
nginx-1.14.2 nginx-1.14.2.tar.gz
(2)、关闭debug日志
[root@server1 ~]# cd nginx-1.14.2
[root@server1 nginx-1.14.2]# vim auto/cc/gcc
171 # debug
172 #CFLAGS="$CFLAGS -g"
(3)、下载编译nginx需要的依赖包
[root@server1 nginx-1.14.2]# yum install pcre-devel zlib-devel gcc -y
(4)、测试存在特性
[root@server1 nginx-1.14.2]# ./configure --prefix=/usr/local/nginx --with-file-aio
(5)、编译安装
[root@server1 nginx-1.14.2]# make && make install
(6)、给配置文件添加高亮(也可以不做)
[root@server1 ~]# mkdir .vim
[root@server1 ~]# cp -r nginx-1.14.2/contrib/vim/* .vim/
3、修改配置文件,启动nginx-1.14.2
[root@server1 nginx-1.14.2]# cd /usr/local/nginx/sbin/
[root@server1 sbin]# ls
nginx nginx.old
[root@server1 sbin]# ./nginx -t #查看nginx配置文件是否正确
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@server1 sbin]# ./nginx -v #查看nginx的版本及测试特性时所加的参数
nginx version: nginx/1.14.2
[root@server1 sbin]# useradd nginx
[root@server1 sbin]# vim ../conf/nginx.conf
1
2 user nginx nginx;
3 worker_processes 2; #设置产生两个worker进程来处理客户请求
4
5 #error_log logs/error.log;
6 #error_log logs/error.log notice;
7 #error_log logs/error.log info;
8
9 #pid logs/nginx.pid;
10
11
12 events {
13 worker_connections 65535; #更改最大连接数
14 }
修改linux资源限制配置文件:
[root@server1 sbin]# vim /etc/security/limits.conf
61 # End of file
62 nginx - nofile 65535
启动nginx
[root@server1 sbin]# ./nginx
4、将nginx-1.14.2平滑升级到nginx-1.15.7
(1)、解压缩
[root@server1 ~]# tar zxf nginx-1.15.7.tar.gz
[root@server1 ~]# ls
nginx-1.14.2 nginx-1.14.2.tar.gz nginx-1.15.7 nginx-1.15.7.tar.gz
(2)、测试存在特性、编译
[root@server1 ~]# cd nginx-1.15.7
[root@server1 nginx-1.15.7]# /usr/local/nginx/sbin/nginx -v
nginx version: nginx/1.14.2
[root@server1 nginx-1.15.7]# ./configure --prefix=/usr/local/nginx --with-file-aio
[root@server1 nginx-1.15.7]# make ##切忌不能make install负责会覆盖老版本的所有相关文件
(3)、查看新版本的二进制执行文件版本
[root@server1 nginx-1.15.7]# cd objs/
[root@server1 objs]# ls
autoconf.err nginx ngx_auto_config.h ngx_modules.c src
Makefile nginx.8 ngx_auto_headers.h ngx_modules.o
[root@server1 objs]# ./nginx -V
nginx version: nginx/1.15.7
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC)
configure arguments: --prefix=/usr/local/nginx --with-file-aio
(4)、备份老版本的二进制可执行文件,可以防止升级失败无法版本回退。
[root@server1 objs]# cd /usr/local/nginx/sbin/
[root@server1 sbin]# ./nginx -v
nginx version: nginx/1.14.2
[root@server1 sbin]# cp nginx nginx.old
[root@server1 sbin]# ls
nginx nginx.old
(5)、将新版本的脚本复制到旧版本的脚本目录下
[root@server1 sbin]# cd -
/root/nginx-1.15.7/objs
[root@server1 objs]# ls
autoconf.err nginx ngx_auto_config.h ngx_modules.c src
Makefile nginx.8 ngx_auto_headers.h ngx_modules.o
[root@server1 objs]# cp -f nginx /usr/local/nginx/sbin/
cp: overwrite ‘/usr/local/nginx/sbin/nginx’? y
(6)、平滑升级
查看到此时nginx的master进程和两个worker进程:
[root@server1 objs]# ps -ef | grep nginx
root 3563 1 0 08:54 ? 00:00:00 nginx: master process ./ngin
nobody 3564 3563 0 08:54 ? 00:00:00 nginx: worker process
nobody 3565 3563 0 08:54 ? 00:00:00 nginx: worker process
root 6135 977 0 09:01 pts/0 00:00:00 grep --color=auto nginx
客户端查看此时生效的nginx服务器:
[root@foundation60 ~]# curl -I 172.25.60.1
HTTP/1.1 200 OK
Server: nginx/1.14.2
Date: Fri, 17 May 2019 01:01:45 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Thu, 16 May 2019 07:52:45 GMT
Connection: keep-alive
ETag: "5cdd16cd-264"
Accept-Ranges: bytes
此时生效的是nginx-1.14.2
Nginx信号简介
主进程支持的信号
TERM, INT: 立刻退出
QUIT: 等待工作进程结束后再退出
KILL: 强制终止进程
HUP: 重新加载配置文件,使用新的配置启动工作进程,并逐步关闭旧进程。
USR1: 重新打开日志文件
USR2: 启动新的主进程,实现热升级
WINCH: 逐步关闭工作进程
工作进程支持的信号
TERM, INT: 立刻退出
QUIT: 等待请求处理结束后再退出
USR1: 重新打开日志文件
1、 在不停掉老进程的情况下,启动新进程。
[root@server1 objs]# ps -ef | grep nginx
root 3563 1 0 08:54 ? 00:00:00 nginx: master process ./ngin
nobody 3564 3563 0 08:54 ? 00:00:00 nginx: worker process
nobody 3565 3563 0 08:54 ? 00:00:00 nginx: worker process
root 6135 977 0 09:01 pts/0 00:00:00 grep --color=auto nginx
注意:此时3563为旧版本的master进程,3564,3565为旧版本接收用户请求的worker进程!!
[root@server1 objs]# kill -USR2 3563
#3563 master进程的两个工作进程不再接收新的请求,只处理当前的请求。同时打开新版本的nginx的master进程,和它的两个工作进程,处理新的用户请求
[root@server1 objs]# ps -ef | grep nginx
root 3563 1 0 08:54 ? 00:00:00 nginx: master process ./ngin
nobody 3564 3563 0 08:54 ? 00:00:00 nginx: worker process
nobody 3565 3563 0 08:54 ? 00:00:00 nginx: worker process
root 6137 3563 0 09:09 ? 00:00:00 nginx: master process ./ngin
nobody 6138 6137 0 09:09 ? 00:00:00 nginx: worker process
nobody 6139 6137 0 09:09 ? 00:00:00 nginx: worker process
root 6141 977 0 09:09 pts/0 00:00:00 grep --color=auto nginx
此时访问,是新的nginx在接受访问
[root@foundation60 ~]# curl -I 172.25.60.1
HTTP/1.1 200 OK
Server: nginx/1.15.7
Date: Fri, 17 May 2019 01:10:16 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Thu, 16 May 2019 07:52:45 GMT
Connection: keep-alive
ETag: “5cdd16cd-264”
Accept-Ranges: bytes
2、 老进程处理完所有请求,关闭所有连接后,停止
[root@server1 objs]# kill -WINCH 3563
[root@server1 objs]# ps -ef | grep nginx
root 3563 1 0 08:54 ? 00:00:00 nginx: master process ./ngin
root 6137 3563 0 09:09 ? 00:00:00 nginx: master process ./ngin
nobody 6138 6137 0 09:09 ? 00:00:00 nginx: worker process
nobody 6139 6137 0 09:09 ? 00:00:00 nginx: worker process
root 6145 977 0 09:11 pts/0 00:00:00 grep --color=auto nginx
kill -WINCH 只会杀掉旧版本master进程的两个worker进程,不会杀掉master进程。等更新完毕后,没有出现问题,才可以杀死旧版本的master进程,则平滑升级完毕!!!
三、版本回退
在实际生产环境中,一旦升级出现任何问题,马上回退到之前的版本
1、将备份好的旧版本的脚本还原
[root@server1 sbin]# pwd
/usr/local/nginx/sbin
[root@server1 sbin]# ls
nginx nginx.old
[root@server1 sbin]# cp -f nginx.old nginx
cp: overwrite ‘nginx’? y
[root@server1 sbin]# ls
nginx nginx.old
2、唤醒旧版本的master进程,使之产生新的worker进程
[root@server1 sbin]# ps -ef | grep nginx
root 3563 1 0 08:54 ? 00:00:00 nginx: master process ./ngin
root 6137 3563 0 09:09 ? 00:00:00 nginx: master process ./ngin
nobody 6138 6137 0 09:09 ? 00:00:00 nginx: worker process
nobody 6139 6137 0 09:09 ? 00:00:00 nginx: worker process
root 6153 977 0 09:18 pts/0 00:00:00 grep --color=auto nginx
[root@server1 sbin]# kill -HUP 3563
[root@server1 sbin]# ps -ef | grep nginx
root 3563 1 0 08:54 ? 00:00:00 nginx: master process ./ngin
root 6137 3563 0 09:09 ? 00:00:00 nginx: master process ./ngin
nobody 6138 6137 0 09:09 ? 00:00:00 nginx: worker process
nobody 6139 6137 0 09:09 ? 00:00:00 nginx: worker process
nobody 6154 3563 0 09:18 ? 00:00:00 nginx: worker process
nobody 6155 3563 0 09:18 ? 00:00:00 nginx: worker process
root 6157 977 0 09:19 pts/0 00:00:00 grep --color=auto nginx
3、使回退版本的worker进程接收新的用户请求。同时新版本的master进程的worker进程不再接收新的用户请求,只处理当前的用户请求
[root@server1 sbin]# kill -USR2 6137
[root@server1 sbin]# ps -ef | grep nginx
root 3563 1 0 08:54 ? 00:00:00 nginx: master process ./ngin
root 6137 3563 0 09:09 ? 00:00:00 nginx: master process ./ngin
nobody 6138 6137 0 09:09 ? 00:00:00 nginx: worker process
nobody 6139 6137 0 09:09 ? 00:00:00 nginx: worker process
nobody 6154 3563 0 09:18 ? 00:00:00 nginx: worker process
nobody 6155 3563 0 09:18 ? 00:00:00 nginx: worker process
root 6160 977 0 09:20 pts/0 00:00:00 grep --color=auto nginx
4、关闭新版本master进程的两个worker进程
[root@server1 sbin]# kill -WINCH 6137
[root@server1 sbin]# ps -ef | grep nginx
root 3563 1 0 08:54 ? 00:00:00 nginx: master process ./ngin
root 6137 3563 0 09:09 ? 00:00:00 nginx: master process ./ngin
nobody 6154 3563 0 09:18 ? 00:00:00 nginx: worker process
nobody 6155 3563 0 09:18 ? 00:00:00 nginx: worker process
root 6162 977 0 09:20 pts/0 00:00:00 grep --color=auto nginx
现在工作的又是旧版本;
[root@foundation60 ~]# curl -I 172.25.60.1
HTTP/1.1 200 OK
Server: nginx/1.14.2
Date: Fri, 17 May 2019 01:21:08 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Thu, 16 May 2019 07:52:45 GMT
Connection: keep-alive
ETag: "5cdd16cd-264"
Accept-Ranges: bytes