2
热部署,就是在应用正在运行的时候升级软件,却不需要重新启动应用。

首先在本地模拟一个线上需要升级 Nginx 的环境,假设旧版本为 nginx-1.0.15,需要升级到 nginx-1.16.0。

配置旧版本

# 下载 nginx-1.0.15
wget http://nginx.org/download/nginx-1.0.15.tar.gz

# 解压压缩包
tar -zxf nginx-1.0.15.tar.gz

# 进入解压后的目录
cd nginx-1.0.15

#  配置 nginx
./configure --prefix=/home/nginx

# 编译安装
make && make install

# 运行 nginx
sudo /home/nginx/sbin/nginx

此时访问服务器地址应该可以看到 nginx 的欢迎页面了。

获得新版本二进制

# 下载 nginx-1.16.0
wget http://nginx.org/download/nginx-1.16.0.tar.gz

# 解压压缩包
tar -zxf nginx-1.16.0

# 进入解压后的目录
cd nginx-1.16.0/

# 配置 nginx
./configure --prefix=/home/nginx

# 只编译不需要安装
make

在编译后的 objs 目录中,可以看到二进制文件 nginx。

热部署

经过以上步骤,我们实现了一个正在运行的旧版本 nginx 和编译完成的新版本 nginx 二进制执行文件。

热部署的流程是:

  1. 备份旧的 nginx 可执行文件
  2. 新的 nginx 可执行文件直接替换旧的(此时旧的 nginx 进程还在运行)
  3. 向 nginx master 进程发送热部署信号,新的 nginx 进程启动,旧的 worker 不再就收请求。
  4. 关闭旧的 worker 进程,完成热部署。
# 备份
cp /home/nginx/sbin/nginx /home/nginx/sbin/nginx.old

# 替换 
cp -f objs/nginx /home/nginx/sbin/nginx

# 查看 master pid
ps -ef | grep nginx 
root     23712     1  0 21:21 ?        00:00:00 nginx: master process /home/nginx/sbin/nginx
nobody   23715 23712  0 21:21 ?        00:00:00 nginx: worker process

# 发送热部署信号,这里 master pid 替换为自己查询到的
kill -USR2 23712

# 查看当前 nginx 进程情况,27522 就是新的 master 进程
ps -ef | grep nginx 
root     23712     1  0 21:21 ?        00:00:00 nginx: master process /home/nginx/sbin/nginx
nobody   23715 23712  0 21:21 ?        00:00:00 nginx: worker process
root     27522 23712  0 21:41 ?        00:00:00 nginx: master process /home/nginx/sbin/nginx
nobody   27524 27522  0 21:41 ?        00:00:00 nginx: worker process

# 关闭旧的 worker
kill -WINCH 23712

# 再次查看进程,可以发现旧的worker进程关闭了
ps -ef | grep nginx 
root     23712     1  0 21:21 ?        00:00:00 nginx: master process /home/nginx/sbin/nginx
root     27522 23712  0 21:41 ?        00:00:00 nginx: master process /home/nginx/sbin/nginx
nobody   27524 27522  0 21:41 ?        00:00:00 nginx: worker process

保留旧的 master 进程是为了在新的版本存在问题时,可以快速回退到原版本。如果发现问题要紧急回滚呢?

cp -f nginx.old nginx
# 拉起旧版本的worker进程(-HUP 相当于 -s reload)
kill -HUP old_master_pid
# 让新版本的 worker 不再接受请求
kill -USR2 new_master_pid
# 关闭新版本的 woker 进程
kill -WINCH new_master_pid

如果确认无误要退出老版本的 nginx,可以执行命令:

kill -QUIT old_master_pid

Donne
694 声望25 粉丝

知其然,知其所以然。