概述
本章,您将学习到 Nginx 的热部署功能。
热部署:在不停止已有 Nginx 程序和中断用户请求的情况下,对 Nginx 的版本进行平滑更新。
Nginx 中的进程
众所周知,当 Nginx 程序启动后,会存在两类进程:
- master 进程 - 主要用来负责读取配置文件、绑定端口、管理或监控 worker 进程、接收外部的命令信号(
nginx -s stop | reload | reopen | quit)。该进程主要担任「管理者」角色,并不实际处理用户的请求 - worker 进程 - 用来处理用户的请求,是真正意义上的「执行者」
热部署的执行步骤
当前旧版本的 Nginx 程序正在运行当中。
-
使用
nginx -V查看当前旧版本 Nginx 的版本信息以及编译选项 -
备份旧 Nginx 程序当中的
nginx二进制可执行文件并命名为nginx.old -
下载新版本 Nginx 的源码压缩包,解压后开始编译安装工作,新版本的编译选项需要与旧版本的编译选项一致
-
使用
ps -lef | grep nginx命令查看 Nginx 的进程信息,如 master 进程的 pid,以及 worker 进程的 pid 与 ppid -
使用
kill -USR2 <pid>将 USR2 信号发送给 master 进程,这里的 pid 替换为实际 master 进程的 pid。命令执行之后会触发以下行为:- 旧 Nginx 程序停止接收新的用户请求
- 旧 Nginx 程序中的 /usr/local/nginx/logs/nginx.pid 会被重命名为 nginx.pid.oldbin。同时会有生成新的 nginx.pid 文件以及新的 master 与 worker 进程
- 在新 Nginx 程序中,新的 master ppid 与旧 master 的 pid 相同
-
再次使用
ps -lef | grep nginx查看进程信息 -
使用
kill -WINCH <pid>给旧 master 进程发信号,让它优雅地关闭旧 worker 进程。若无问题,则使用kill <pid>直接结束旧 master 进程;若有问题,则使用kill -HUB <pid>重新拉起旧 worker 进程
实际操作
需求:使用热部署功能将 Nginx 的 1.30.4 版本更新到 1.31.5 版本
步骤一:启动 Nginx 程序,查看版本信息与编译选项
Shell > /usr/local/nginx/sbin/nginx -t && /usr/local/nginx/sbin/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
Shell > /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.30.4
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-28) (GCC)
built with OpenSSL 1.1.1k FIPS 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --sbin-path=/usr/local/nginx/sbin/nginx --modules-path=/usr/local/nginx/modules --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_v3_module --with-http_realip_module --with-http_gzip_static_module --with-http_dav_module --with-stream --with-threads --with-file-aio --with-compat
步骤二:备份旧 Nginx 程序当中的 nginx 二进制可执行文件并命名为 nginx.old
Shell > cd /usr/local/nginx/sbin/
Shell > mv nginx nginx.old
步骤三:下载新版本 Nginx 的源码压缩包,解压后开始编译安装工作,新版本的编译选项需要与旧版本的编译选项一致
Shell > cd
# 下载源码压缩包
Shell > wget -c https://nginx.org/download/nginx-1.31.5.tar.gz
# 对压缩包解压并提取文件
Shell > tar -vxf nginx-1.31.5.tar.gz -C /usr/local/src/
# 切换工作目录
Shell > cd /usr/local/src/nginx-1.31.5/
# 开始编译与安装工作
Shell > ./configure \
--prefix=/usr/local/nginx \
--sbin-path=/usr/local/nginx/sbin/nginx \
--modules-path=/usr/local/nginx/modules \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_v3_module \
--with-http_realip_module \
--with-http_gzip_static_module \
--with-http_dav_module \
--with-stream \
--with-threads \
--with-file-aio \
--with-compat \
&& make && make install
# 查看新版本的信息
Shell > /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.31.5
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-28) (GCC)
built with OpenSSL 1.1.1k FIPS 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --sbin-path=/usr/local/nginx/sbin/nginx --modules-path=/usr/local/nginx/modules --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_v3_module --with-http_realip_module --with-http_gzip_static_module --with-http_dav_module --with-stream --with-threads --with-file-aio --with-compat
步骤四:查看 Nginx 中的进程信息
Shell > ps -lef | grep nginx
1 S root 5749 1 0 80 0 - 6945 - 12:15 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
5 S nginx 5750 5749 0 80 0 - 12170 do_epo 12:15 ? 00:00:00 nginx: worker process
5 S nginx 5751 5749 0 80 0 - 12170 do_epo 12:15 ? 00:00:00 nginx: worker process
5 S nginx 5752 5749 0 80 0 - 12170 do_epo 12:15 ? 00:00:00 nginx: worker process
5 S nginx 5753 5749 0 80 0 - 12170 do_epo 12:15 ? 00:00:00 nginx: worker process
0 S root 5763 4542 0 80 0 - 3055 - 12:18 pts/0 00:00:00 grep --color=auto nginx
从命令输出可以看到,master 进程的 pid 为 5749,所有 worker 进程的 ppid 都是 5749
步骤五:将 USR2 信号发送给 master 进程
Shell > kill -USR2 5749
Shell > ls -l /usr/local/nginx/logs/nginx.pid*
-rw-r--r-- 1 root root 5 Sep 12 12:29 /usr/local/nginx/logs/nginx.pid
-rw-r--r-- 1 root root 5 Sep 12 12:15 /usr/local/nginx/logs/nginx.pid.oldbin
步骤六:再次查看进程信息
Shell > ps -lef | grep nginx
1 S root 5749 1 0 80 0 - 6945 - 12:15 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
5 S nginx 5750 5749 0 80 0 - 12170 do_epo 12:15 ? 00:00:00 nginx: worker process
5 S nginx 5751 5749 0 80 0 - 12170 do_epo 12:15 ? 00:00:00 nginx: worker process
5 S nginx 5752 5749 0 80 0 - 12170 do_epo 12:15 ? 00:00:00 nginx: worker process
5 S nginx 5753 5749 0 80 0 - 12170 do_epo 12:15 ? 00:00:00 nginx: worker process
4 S root 9362 5749 0 80 0 - 6959 - 12:29 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
5 S nginx 9363 9362 0 80 0 - 12181 do_epo 12:29 ? 00:00:00 nginx: worker process
5 S nginx 9364 9362 0 80 0 - 12181 do_epo 12:29 ? 00:00:00 nginx: worker process
5 S nginx 9365 9362 0 80 0 - 12181 do_epo 12:29 ? 00:00:00 nginx: worker process
5 S nginx 9366 9362 0 80 0 - 12181 do_epo 12:29 ? 00:00:00 nginx: worker process
0 S root 9383 4542 0 80 0 - 3055 - 12:31 pts/0 00:00:00 grep --color=auto nginx
查看命令的输出可知,新版本 Nginx 中 master 进程的 pid 为 9362,ppid 为 5749,与旧版本中 msater 进程的 5749 对应上了
步骤七:给旧 master 进程发送信号,使其优雅关闭对应的 worker 进程
Shell > kill -WINCH 5749
尝试访问,没问题:
Shell > curl http://192.168.100.20
This is the GAMES page
接着关闭旧 master 进程:
Shell > kill 5749
此时的进程信息如下:
Shell > ps -lef | grep nginx
4 S root 9362 1 0 80 0 - 6959 - 12:29 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
5 S nginx 9363 9362 0 80 0 - 12181 do_epo 12:29 ? 00:00:00 nginx: worker process
5 S nginx 9364 9362 0 80 0 - 12181 do_epo 12:29 ? 00:00:00 nginx: worker process
5 S nginx 9365 9362 0 80 0 - 12181 do_epo 12:29 ? 00:00:00 nginx: worker process
5 S nginx 9366 9362 0 80 0 - 12181 do_epo 12:29 ? 00:00:00 nginx: worker process
0 S root 9390 4542 0 80 0 - 3055 - 12:38 pts/0 00:00:00 grep --color=auto nginx
平滑无感知的版本更新完成。









