基于 LNMP 的 Nginx 百万并发之路 (四)热部署

Nginx 热部署或者说平滑升级是指不中断服务器服务同时更新版本。通俗地说就是不打断用户请求,让用户的体验感处于一个高水平线。可以试想,如果一个用户在购物车放置了大量限时优惠商品,正准备结算,突然网页出现工程师 24 小时修复中的提示页面,会很烦恼吧。

信号量

Nginx 的热部署跟 Linux 信号量机制有密切关系,先查看 Linux 信号量 kill -l,显示如下

 1) SIGHUP     2) SIGINT             3) SIGQUIT      4) SIGILL        5) SIGTRAP
 6) SIGABRT     7) SIGBUS     8) SIGFPE             9) SIGKILL    10) SIGUSR1
11) SIGSEGV    12) SIGUSR2    13) SIGPIPE    14) SIGALRM    15) SIGTERM
16) SIGSTKFLT    17) SIGCHLD    18) SIGCONT    19) SIGSTOP    20) SIGTSTP
21) SIGTTIN    22) SIGTTOU    23) SIGURG    24) SIGXCPU    25) SIGXFSZ
26) SIGVTALRM    27) SIGPROF    28) SIGWINCH    29) SIGIO    30) SIGPWR
31) SIGSYS    34) SIGRTMIN    35) SIGRTMIN+1    36) SIGRTMIN+2    37) SIGRTMIN+3
38) SIGRTMIN+4    39) SIGRTMIN+5    40) SIGRTMIN+6    41) SIGRTMIN+7    42) SIGRTMIN+8
43) SIGRTMIN+9    44) SIGRTMIN+10    45) SIGRTMIN+11    46) SIGRTMIN+12    47) SIGRTMIN+13
48) SIGRTMIN+14    49) SIGRTMIN+15    50) SIGRTMAX-14    51) SIGRTMAX-13    52) SIGRTMAX-12
53) SIGRTMAX-11    54) SIGRTMAX-10    55) SIGRTMAX-9    56) SIGRTMAX-8    57) SIGRTMAX-7
58) SIGRTMAX-6    59) SIGRTMAX-5    60) SIGRTMAX-4    61) SIGRTMAX-3    62) SIGRTMAX-2
63) SIGRTMAX-1    64) SIGRTMAX

一共 64 种,其中常见的命令为 kill -15 表示快速关闭,kill -9 强制关闭,kill -1 重新读取配置文件,kill - 17 父子进程通信等等。

信号量 描述
USR2 Upgrade Executable on the fly 平滑升级
WINCH Gracefully shutdown the worker processes 优雅关闭旧的进程(配合USR2来进行升级)
HUP Configuration reload ,Start the new worker processes with a new configuration Gracefully shutdown the old worker processes 改变配置文件,平滑重读配置文件

热部署

用全路径形式开启 Nginx

/opt/nginx/sbin/nginx

以防万一,备份 Nginx 二进制文件与主配置文件,其实安装新版本后也会在 sbin 目录生成一个 nginx.old 二进制文件,这属于旧版本的。

cp /opt/nginx/sbin/nginx /opt/nginx/sbin/nginx.bk
cp /opt/nginx/conf/nginx.conf /opt/nginx/conf/nginx.conf.bk

ls /opt/nginx/sbin

nginx
nginx.bk

下载需要更新的 Nginx 版本

wget http://nginx.org/download/nginx-1.19.2.tar.gz

注意安装目录须于原版本一致,查看安装目录 nginx -V

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: --prefix=/opt/nginx --conf-path=/opt/nginx/conf/nginx.conf --user=nginx --group=nginx --pid-path=/opt/nginx/pid/nginx.pid --error-log-path=/opt/nginx/logs/error.log --with-pcre=/opt/source/pcre-8.44 --with-zlib=/opt/source/zlib-1.2.11 --with-http_ssl_module --with-http_image_filter_module --with-http_stub_status_module --http-log-path=/opt/nginx/logs/access.log --with-http_auth_request_module

lscpu

CPU(s): 4

ps -ef | grep nginx | grep -v grep

root       2088      1  0 01:03 ?        00:00:00 nginx: master process /opt/nginx/sbin/nginx
nginx      2089   2088  0 01:03 ?        00:00:00 nginx: worker process
nginx      2090   2088  0 01:03 ?        00:00:00 nginx: worker process
nginx      2091   2088  0 01:03 ?        00:00:00 nginx: worker process
nginx      2092   2088  0 01:03 ?        00:00:00 nginx: worker process

发送 USE2 命令

kill -s SIGUSR2 2088

再次查看 Nginx 进程,发现同时存在 8 个子进程,其中多出的 4 个是使用新版本的子进程。

root       2088      1  0 01:03 ?        00:00:00 nginx: master process /opt/nginx/sbin/nginx
nginx      2089   2088  0 01:03 ?        00:00:00 nginx: worker process
nginx      2090   2088  0 01:03 ?        00:00:00 nginx: worker process
nginx      2091   2088  0 01:03 ?        00:00:00 nginx: worker process
nginx      2092   2088  0 01:03 ?        00:00:00 nginx: worker process
root       2096   2088  0 01:04 ?        00:00:00 nginx: master process /opt/nginx/sbin/nginx
nginx      2097   2096  0 01:04 ?        00:00:00 nginx: worker process
nginx      2098   2096  0 01:04 ?        00:00:00 nginx: worker process
nginx      2099   2096  0 01:04 ?        00:00:00 nginx: worker process
nginx      2100   2096  0 01:04 ?        00:00:00 nginx: worker process

ll /opt/nginx/logs/

nginx.pid # 新版本进程 id 2096
nginx.pid.oldbin # 旧版本进程 id 2088

发送 WINCH 信号,关闭旧的子进程。

kill -s SIGWINCH 2088

查看现有版本 nginx -V

nginx version: nginx/1.19.2

优雅关闭旧 master 进程。在这一步可以不关闭旧 master 进程,测试新版本,如果不达预期可以直接回滚至旧版本。

kill -s SIGQUIT 2088

这时候用 ps 命令查看,已经为新版本的 Nginx 进程(演示)。

root       2096      1  0 01:04 ?        00:00:00 nginx: master process /opt/nginx/sbin/nginx
nginx      2097   2096  0 01:04 ?        00:00:00 nginx: worker process
nginx      2098   2096  0 01:04 ?        00:00:00 nginx: worker process
nginx      2099   2096  0 01:04 ?        00:00:00 nginx: worker process
nginx      2100   2096  0 01:04 ?        00:00:00 nginx: worker process

回滚

如果测试后发现新版本不适应现有业务,可以进行像数据库那样的回滚操作。

kill -s SIGHUP 2088 # 此命令将拉起旧的子进程
kill -s SIGQUIT 2096  # r让新版本的子进程优雅退出

ps -ef | grep nginx | grep -v grep 查看,发现旧的 master 已经启动 4 个子进程,新版本的主进程与子进程完全退出。

root       2088      1  0 01:03 ?        00:00:00 nginx: master process /opt/nginx/sbin/nginx
nginx      2100   2088  0 01:03 ?        00:00:00 nginx: worker process
nginx      2101   2088  0 01:03 ?        00:00:00 nginx: worker process
nginx      2102   2088  0 01:03 ?        00:00:00 nginx: worker process
nginx      2103   2088  0 01:03 ?        00:00:00 nginx: worker process
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!