# 热部署

热部署的概念:当从老版本替换为新版本的nginx的时候,如果不热部署的话,会需要取消nginx服务并重启服务才能替换成功,这样的话会使正在访问的用户在断开连接,所以为了不影响用户的体验,且需要版本升级,就需要热部署来升级版本

# 备份

找到 nginx 安装程序目录

[root@nginx01 ~]# whereis nginx
nginx: /usr/local/nginx
[root@nginx01 ~]# cd /usr/local/nginx
[root@nginx01 nginx]# ll
total 4
drwxr-xr-x. 2 root root 4096 Sep 20 11:09 conf
drwxr-xr-x. 2 root root   40 Sep 20 11:09 html
drwxr-xr-x. 2 root root   36 Sep 20 11:33 sbin
[root@nginx01 nginx]# cd ./sbin
[root@nginx01 sbin]# ll
total 7536
-rwxr-xr-x. 1 root root 3857520 Sep 20 11:33 nginx

然后,备份 nginx 二进制文件。

cp nginx nginx.old

# 替换 nginx 进程文件

接下来需要把新版本编译好的二进制文件,拷贝到当前目录中,替换掉正在运行的 nginx 进程所使用的 nginx 文件。

-rwxr-xr-x. 1 root root 1578907 Sep 20 11:33 nginx
-rwxr-xr-x. 1 root root 3857520 Sep 20 14:58 nginx.old

# 发送 USR2 信号

首先查看 master 进程的 pid 号。

[root@nginx01 sbin]# ps -ef |grep nginx
root     17627     1  0 11:35 ?        00:00:00 nginx: master process ./nginx
nobody   17812 17627  0 14:50 ?        00:00:00 nginx: worker process
root     17843  1609  0 15:14 pts/0    00:00:00 grep --color=auto nginx

然后,需要给正在运行的 master 的进程发送一个通知消息,告诉它我们开始进行热部署了,需要进行一次版本升级。

kill -USR2 17627

执行上面的指令,会新启动一个 master 进程,新启动的 master 进程,会依赖上面复制过来的新版本编译好的二进制文件。

同时老的 worker 进程,依然会运行。新的 master 进程,会产生新的 worker 进程。会进行平滑的过度。

查看新的进程状况:

[root@nginx01 sbin]# ps -ef |grep nginx
root     17627     1  0 11:35 ?        00:00:00 nginx: master process ./nginx
nobody   17812 17627  0 14:50 ?        00:00:00 nginx: worker process
root     17845 17627  0 15:15 ?        00:00:00 nginx: master process ./nginx
nobody   17846 17845  0 15:15 ?        00:00:00 nginx: worker process
root     17849  1609  0 15:19 pts/0    00:00:00 grep --color=auto nginx

新,老 masterworker 进程都在运行,老的进程不会监听 80,443 等这些端口了。新的请求,会由新的进程进行接收,处理。

# 发送 WINCH 信号

给老的 master 进程发送 WINCH 信号,告诉它优雅的关闭所有的 worker 进程。

[root@nginx01 sbin]# kill -WINCH 17627
[root@nginx01 sbin]# ps -ef |grep nginx
root     17627     1  0 11:35 ?        00:00:00 nginx: master process ./nginx
root     17845 17627  0 15:15 ?        00:00:00 nginx: master process ./nginx
nobody   17846 17845  0 15:15 ?        00:00:00 nginx: worker process
nobody   17851 17627  0 15:27 ?        00:00:00 nginx: worker process
root     17853  1609  0 15:27 pts/0    00:00:00 grep --color=auto nginx

从上面我们可以了解到,老的 worker 17812 进程,已经退出了。所有的请求已经成功切换到新升级的nginx中了。

此外,如果我们升级,产生了新的问题。由于,老的 master 17627 进程依然存在。我们可以给老的 master 17627 进程,发送 reload 命名。让它重新把worker 进程拉起来,再把新版本关掉。实现版本回退的功能。

可以用 kill -QUIT 把老的 master 进程杀掉。

# 版本回退

# 替换 nginx 进程文件

将之前备份的旧版本的nginx二进制文件强行覆盖新版的nginx二进制文件。

mv nginx.old nginx

# 发送 HUP 信号

向上面旧版本的 master 进程,发送 HUP 信号。

kill -HUP 17627

HUP 是对应 reload 命令`。

reload 实际上是向 master 进程发送 HUP 信号要求重启 worker 进程,如果 master 进程下没有 worker 进程,则相当于按 nginx.conf 启动worker 进程,因此向老 master发送 HUP 则相当于把老版本的 Nginx 恢复处理请求了。

# 发送 USR2 信号

向上面新版本的 master 进程,发送 USR2 信号。

让新版本的nginx服务停止接收用户请求。

kill -USR2 17845

# 发送 WINCH 信号

向上面新版本的 master 进程,发送 WINCH 信号。

让新版本nginx的worker进程退出服务

kill -WINCH 17845

# 参考

更新时间: 9/22/2020, 3:13:23 AM