nginx的平滑升级重要性
由于nginx的优越性能及强大功能,被业界大量使用,Nginx版本升级必然是越来越快的,以优化自身性能或修复安全漏洞。同时线上业务又不能停,此时nginx的平滑升级就显得尤为重要。
安全漏洞报告
nginx升级原理简介
多进程模式下的请求分配方式
Nginx默认工作在多进程模式下,即主进程(master process)启动后完成配置加载和端口绑定等动作,fork出指定数量的工作进程(worker process),这些子进程会持有监听端口的文件描述符(fd),并通过在该描述符上添加监听事件来接受连接(accept)。
信号的接收和处理
Nginx主进程在启动完成后会进入等待状态,负责响应各类系统消息,如SIGCHLD、SIGHUP、SIGUSR2等。
Nginx信号简介
主进程支持的信号
- TERM, INT: 立刻退出
- QUIT: 等待工作进程结束后再退出
- KILL: 强制终止进程
- HUP: 重新加载配置文件,使用新的配置启动工作进程,并逐步 关闭旧进程。
- USR1: 重新打开日志文件
- USR2: 启动新的主进程,实现热升级
- WINCH: 逐步关闭工作进程
工作进程支持的信号
- TERM, INT: 立刻退出
- QUIT: 等待请求处理结束后再退出
- USR1: 重新打开日志文件
nginx平滑升级详细过程
1、环境准备
- 查看当前版本及编译参数
[root@izwz96u1ukkfo2ki7ywqbiz local]# nginx -V
nginx version: nginx/1.14.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --with-http_ssl_module --with-http_stub_status_module
- 上传新版本nginx-1.17.9
D:\soft>scp nginx-1.17.9.tar.gz root@120.79.xxx.xxx:/opt/soft
root@120.79.xxx.xxx's password:
nginx-1.17.9.tar.gz 100% 1015KB 3.4MB/s 00:00
D:\soft>
- 解压、编译新版本Nginx源码,安装路径必须与旧版本一致,且不能执行make install
[root@izwz96u1ukkfo2ki7ywqbiz soft]# ll
total 1020
drwxr-xr-x 9 1001 erposm 4096 Oct 12 2018 nginx-1.14.0
-rw-r--r-- 1 root root 1039136 Mar 19 11:19 nginx-1.17.9.tar.gz
[root@izwz96u1ukkfo2ki7ywqbiz soft]# tar -zxf nginx-1.17.9.tar.gz
[root@izwz96u1ukkfo2ki7ywqbiz soft]# ll
total 1024
drwxr-xr-x 9 1001 erposm 4096 Oct 12 2018 nginx-1.14.0
drwxr-xr-x 8 1001 erposm 4096 Mar 3 23:04 nginx-1.17.9
-rw-r--r-- 1 root root 1039136 Mar 19 11:19 nginx-1.17.9.tar.gz
- 配置源码,务必保持与老版本参数一致
[root@izwz96u1ukkfo2ki7ywqbiz soft]# cd nginx-1.17.9
[root@izwz96u1ukkfo2ki7ywqbiz nginx-1.17.9]# ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module
checking for OS
+ Linux 3.10.0-693.2.2.el7.x86_64 x86_64
······
creating objs/Makefile
Configuration summary
+ using system PCRE library
+ using system OpenSSL library
+ using system zlib library
nginx path prefix: "/usr/local/nginx"
nginx binary file: "/usr/local/nginx/sbin/nginx"
nginx modules path: "/usr/local/nginx/modules"
nginx configuration prefix: "/usr/local/nginx/conf"
nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
nginx pid file: "/usr/local/nginx/logs/nginx.pid"
nginx error log file: "/usr/local/nginx/logs/error.log"
nginx http access log file: "/usr/local/nginx/logs/access.log"
nginx http client request body temporary files: "client_body_temp"
nginx http proxy temporary files: "proxy_temp"
nginx http fastcgi temporary files: "fastcgi_temp"
nginx http uwsgi temporary files: "uwsgi_temp"
nginx http scgi temporary files: "scgi_temp"
[root@izwz96u1ukkfo2ki7ywqbiz nginx-1.17.9]#
- 编译:make
[root@izwz96u1ukkfo2ki7ywqbiz nginx-1.17.9]# make
make -f objs/Makefile
make[1]: Entering directory `/opt/soft/nginx-1.17.9'
cc -c -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
-o objs/src/core/nginx.o \
src/core/nginx.c
······
-Wl,-E
sed -e "s|%%PREFIX%%|/usr/local/nginx|" \
-e "s|%%PID_PATH%%|/usr/local/nginx/logs/nginx.pid|" \
-e "s|%%CONF_PATH%%|/usr/local/nginx/conf/nginx.conf|" \
-e "s|%%ERROR_LOG_PATH%%|/usr/local/nginx/logs/error.log|" \
< man/nginx.8 > objs/nginx.8
make[1]: Leaving directory `/opt/soft/nginx-1.17.9'
[root@izwz96u1ukkfo2ki7ywqbiz nginx-1.17.9]#
- 备份二进制文件,用新版本代替
[root@izwz96u1ukkfo2ki7ywqbiz nginx-1.17.9]mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old
[root@izwz96u1ukkfo2ki7ywqbiz nginx-1.17.9]# ls
auto CHANGES CHANGES.ru conf configure contrib html LICENSE Makefile man objs README src
[root@izwz96u1ukkfo2ki7ywqbiz nginx-1.17.9]# ls objs/
autoconf.err Makefile nginx nginx.8 ngx_auto_config.h ngx_auto_headers.h ngx_modules.c ngx_modules.o src
[root@izwz96u1ukkfo2ki7ywqbiz nginx-1.17.9]# cp objs/nginx /usr/local/nginx/sbin/
cp: overwrite ‘/usr/local/nginx/sbin/nginx’? y
[root@izwz96u1ukkfo2ki7ywqbiz nginx-1.17.9]# ll /usr/local/nginx/sbin/
total 11460
-rwxr-xr-x 1 root root 5949736 Mar 19 12:24 nginx
-rwxr-xr-x 1 root root 5783064 Jun 22 2018 nginx.old
[root@izwz96u1ukkfo2ki7ywqbiz nginx-1.17.9]#
- 检验新版本是否可用
[root@izwz96u1ukkfo2ki7ywqbiz nginx-1.17.9]# nginx -t
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@izwz96u1ukkfo2ki7ywqbiz nginx-1.17.9]#
2、 开始升级
[root@localhost sbin]# ps -ef|grep nginx
root 24772 1 0 1月10 ? 00:00:00 nginx: master process ./nginx
nobody 24925 24772 0 1月10 ? 00:20:43 nginx: worker process
root 28168 24991 0 21:46 pts/0 00:00:00 grep --color=auto nginx
[root@izwz96u1ukkfo2ki7ywqbiz nginx-1.17.9]#
- 向主进程(master)发送USR2信号。Nginx会启动一个新版本的master进程和对应的工作进程和旧版本一起处理请求
重新启动了worker进程
[root@localhost sbin]# kill -USR2 24772
[root@localhost sbin]# ps -ef|grep nginx
root 24772 1 0 1月10 ? 00:00:00 nginx: master process ./nginx
nobody 24925 24772 0 1月10 ? 00:20:43 nginx: worker process
root 28222 24772 0 21:47 ? 00:00:00 nginx: master process ./nginx
nobody 28224 28222 0 21:47 ? 00:00:00 nginx: worker process
root 28227 24991 0 21:47 pts/0 00:00:00 grep --color=auto nginx
[root@localhost sbin]#
- 查看升级后的版本
[root@izwz96u1ukkfo2ki7ywqbiz nginx-1.17.9]# nginx -V
nginx version: nginx/1.17.9
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module
[root@izwz96u1ukkfo2ki7ywqbiz nginx-1.17.9]#
通过发送WINCH信号(平缓停止worker process)和QUIT信号(平缓停止Nginx服务)停止旧的Nginx服务进程
kill -WINCH cat /usr/local/nginx/logs/nginx.pid.oldbin
kill -QUIT cat /usr/local/nginx/logs/nginx.pid.oldbin