前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除
一、为什么要对nginx平滑升级
随着 nginx 越来越流行,并且 nginx 的优势也越来越明显, nginx 的版本迭代也来时加速模式,1.9.0版本的nginx更新了许多新功能,例如 stream 四层代理功能,伴随着 nginx 的广泛应用,版本升级必然越来越快,线上业务不能停,此时 nginx 的升级就需要平滑升级;要求nginx是源码编译安装的
nginx实现平滑升级原理简单概括:
- 在不停掉老进程的情况下,启动新进程
- 老进程负责处理仍然没有处理完的请求,但不再接受处理请求
- 新进程接受新请求
-
老进程处理完所有请求,关闭所有连接后,停止
这样就很方便地实现了平滑升级。一般有两种情况下需要升级 nginx,一种是确实要升级 nginx 的版本,另一种是要为 nginx 添加新的模块。
二、Nginx平滑升级原理
1、多进程模式下的请求分配方式
nginx 默认工作在多进程模式下,即主进程(master process)启动后完成配置加载和端口绑定等动作, fork 出指定数量的工作进程(worker process),这些子进程会持有监听端口的文件描述符(fd),并通过在该描述符上添加监听事件来接受连接(accept)。
2、信号的接收和处理
nginx 主进程在启动完成后会进入等待状态,负责响应各类系统消息,如SIGCHLD、SIGHUP、SIGUSR2等
3、Nginx信号简介
3.1、主进程支持的信号
信号 | 说明 |
---|---|
TERM,INT | 立刻退出 |
QUIT | 等待工作进程结束后再退出 |
KILL | 强制终止进程 |
HUP | 重新加载配置文件,使用新的配置启动工作进程,并逐步关闭旧进程 |
USR1 | 重新打开日志文件 |
USR2 | 启动新的主进程,实现热升级 |
WINCH | 逐步关闭工作进程 |
3.2、工作进程支持的信号
信号 | 说明 |
---|---|
TERM,INT | 立刻退出 |
QUIT | 等待请求处理结束后再退出 |
USR1 | 重新打开日志文件 |
三、Nginx平滑升级实验
1、源码编译安装的平滑升级
(1)编写nginx主页,以测试nginx的平滑升级
[root@localhost ~]# echo "nginx1.16.0" > /usr/local/nginx/html/index.html
[root@localhost ~]# vim /etc/nginx/nginx.conf
server {
listen 80;
server_name localhost;
location / {
root /usr/local/nginx/html/;
index index.html index.htm;
}
}
[root@localhost ~]# nginx -s reload
浏览器测试访问
(2)查看现有的nginx编译参数
[root@localhost ~]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.16.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 --group=nginx --user=nginx --sbin-path=/usr/local/nginx/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/tmp/nginx/client_body --http-proxy-temp-path=/tmp/nginx/proxy --http-fastcgi-temp-path=/tmp/nginx/fastcgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-pcre --with-http_realip_module --with-stream
(3)下载新版本的源码包并解压到原版本安装目录
[root@localhost ~]# wget http://nginx.org/download/nginx-1.26.0.tar.gz
[root@localhost ~]# tar xzf nginx-1.26.0.tar.gz -C /usr/local/
(4)将新版本源码进行编译配置
[root@localhost local]# cd /usr/local/nginx-1.26.0/
[root@localhost nginx-1.26.0]# ./configure \
--prefix=/usr/local/nginx \
--group=nginx \
--user=nginx \
--sbin-path=/usr/local/nginx/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--http-client-body-temp-path=/tmp/nginx/client_body \
--http-proxy-temp-path=/tmp/nginx/proxy \
--http-fastcgi-temp-path=/tmp/nginx/fastcgi \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/lock/nginx \
--with-http_stub_status_module \
--with-http_ssl_module \
--with-http_gzip_static_module \
--with-pcre \
--with-http_realip_module \
--with-stream
[root@localhost nginx-1.26.0]# make
[root@localhost nginx-1.26.0]# cd /usr/local
[root@localhost local]# ls
bin etc games include lib lib64 libexec nginx nginx-1.16.0 nginx-1.26.0 sbin share src
(5) 备份旧版 Nginx并替换新版 Nginx
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx_bak
cp /usr/local/nginx-1.26.0/objs/nginx /usr/local/nginx/sbin/
(6)测试新版本的nginx是否正常
[root@localhost local]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
(7)给nginx发送平滑迁移信号(若不清楚pid路径,请查看nginx配置文件)
kill -USR2 `cat /var/run/nginx.pid`
(8)查看nginx pid,会出现一个nginx.pid.oldbin
[root@localhost local]# ll /var/run/nginx.pid*
-rw-r--r-- 1 root root 5 Aug 14 18:04 /var/run/nginx.pid
-rw-r--r-- 1 root root 5 Aug 14 18:00 /var/run/nginx.pid.oldbin
# 并且查看进程也会有两个nginx进程
[root@localhost local]# ps aux | grep nginx
root 3339 0.0 0.0 46204 1964 ? Ss 18:00 0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 3342 0.0 0.0 48728 2352 ? S 18:00 0:00 nginx: worker process
root 6424 0.0 0.0 46116 3340 ? S 18:04 0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 6425 0.0 0.0 48652 1984 ? S 18:04 0:00 nginx: worker process
root 6437 0.0 0.0 112812 980 pts/2 S+ 18:05 0:00 grep --color=auto nginx
(9)从容关闭旧的Nginx进程
kill -WINCH `cat /var/run/nginx.pid.oldbin`
(10)此时不重载配置启动旧的工作进程
kill -HUP `cat /var/run/nginx.pid.oldbin`
(11)结束工作进程,完成此次升级
kill -QUIT `cat /var/run/nginx.pid.oldbin`
(12)验证Nginx是否升级成功;
[root@localhost local]# ps aux | grep nginx
root 6424 0.0 0.0 46116 3340 ? S 18:04 0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 6425 0.0 0.0 48652 2236 ? S 18:04 0:00 nginx: worker process
nginx 6484 0.0 0.0 48728 2348 ? S 18:09 0:00 nginx: worker process
root 56303 0.0 0.0 112812 980 pts/2 S+ 18:22 0:00 grep --color=auto nginx
[root@localhost local]# nginx -v
nginx version: nginx/1.26.0
查看网页测试,至此实现平滑升级
致谢
在此,我要对所有为知识共享做出贡献的个人和机构表示最深切的感谢。同时也感谢每一位花时间阅读这篇文章的读者,如果文章中有任何错误,欢迎留言指正。
学习永无止境,让我们共同进步!!