nginx平滑升级
4 min read

nginx平滑升级

一、nginx 平滑升级概述

随着网站并发访问量越来越高,nginx Web 服务器也越来越流行,nginx 版本换代越来越频繁,1.16.1 版本的 nginx 更新了许多新功能,生产环境中版本升级必然的,但是线上业务不能停,此时 nginx 的升级就是运维的重要工作了。

二、nginx 平滑升级原理

多进程模式下的请求分配方式
Nginx 默认工作在多进程模式下,即主进程(master process)启动后完成配置加载和端口绑定等动作,fork 出指定数量的工作进程(worker process),这些子进程会持有监听端口的文件描述符(fd),并通过在该描述符上添加监听事件来接受连接(accept)。

信号的接收和处理
Nginx 主进程在启动完成后会进入等待状态,负责响应各类系统消息,如 SIGCHLD、SIGHUP、SIGUSR2 等。

  • 主进程支持的信号
    TERM, INT: 立刻退出
    QUIT: 等待工作进程结束后再退出
    KILL: 强制终止进程
    HUP: 重新加载配置文件,使用新的配置启动工作进程,并逐步关闭旧进程。
    USR1: 重新打开日志文件
    USR2: 启动新的主进程,实现热升级
    WINCH: 逐步关闭工作进程
  • 工作进程支持的信号
    TERM, INT: 立刻退出
    QUIT: 等待请求处理结束后再退出
    USR1: 重新打开日志文件

三、nginx 平滑升级实战
1.查看旧版 nginx 的编译参数

# nginx -V
nginx version: nginx/1.14.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-stream --with-http_gzip_static_module --with-http_sub_module

2.编译新版本 Nginx 源码包,安装路径需与旧版一致,注意:不要执行 make install

# cd /usr/local/src
# wget http://nginx.org/download/nginx-1.16.1.tar.gz
# tar xf nginx-1.16.1.tar.gz
# cd /usr/local/src/nginx-1.16.1/
# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module --with-http_flv_module --with-http_gzip_static_module
# make

3.备份二进制文件,用新版本的替换

# mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx-1.14.0
# cp /usr/local/src/nginx-1.16.1/objs/nginx /usr/local/nginx/sbin/

4.确保配置文件无报错

# /usr/local/nginx/sbin/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

5.发送 USR2 信号
向主进程(master)发送 USR2 信号,Nginx 会启动一个新版本的 master 进程和对应工作进程,和旧版一起处理请求

# ps aux | grep nginx
root 16396 0.0 0.5 47136 2684 ? Ss 14:49 0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 16404 0.0 0.7 47532 3548 ? S 14:54 0:00 nginx: worker process
root 21993 0.0 0.2 112724 996 pts/1 S+ 20:42 0:00 grep --color=auto nginx
# kill -USR2 16396
# ps aux | grep nginx
root 16396 0.0 0.5 47136 2684 ? Ss 14:49 0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 16404 0.0 0.7 47532 3548 ? S 14:54 0:00 nginx: worker process
root 21994 0.0 0.6 45968 3288 ? S 20:44 0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 21995 0.0 0.3 46428 1892 ? S 20:44 0:00 nginx: worker process
root 21997 0.0 0.2 112724 996 pts/1 R+ 20:44 0:00 grep --color=auto nginx

6.发送 WINCH 信号
向旧的 Nginx 主进程(master)发送 WINCH 信号,它会逐步关闭自己的工作进程(主进程不退出),这时所有请求都会由新版 Nginx 处理

# kill -WINCH 16396
# ps aux | grep nginx
root 16396 0.0 0.5 47136 2684 ? Ss 14:49 0:00 nginx: master process /usr/local/nginx/sbin/nginx
root 21994 0.0 0.6 45968 3288 ? S 20:44 0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 21995 0.0 0.3 46428 1892 ? S 20:44 0:00 nginx: worker process

注意:回滚步骤,发送 HUP 信号
如果这时需要回退继续使用旧版本,可向旧的 Nginx 主进程发送 HUP 信号,它会重新启动工作进程, 仍使用旧版配置文件。然后可以将新版 Nginx 进程杀死(使用 QUIT、TERM、或者 KILL)

# kill -HUP 16396

7.发送 QUIT 信号
升级完毕,可向旧的 Nginx 主进程(master)发送(QUIT、TERM、或者 KILL)信号,使旧的主进程退出

# kill -QUIT 16396
# ps aux | grep nginx
root 21994 0.0 0.6 45968 3288 ? S 20:44 0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 21995 0.0 0.3 46428 1892 ? S 20:44 0:00 nginx: worker process

8.验证 nginx 版本号,并访问测试

# /usr/local/nginx/sbin/nginx -v
nginx version: nginx/1.16.1
京ICP备19055754号