平滑升级和回滚的前提条件是 nginx 已经安装好,源码安装 nginx 可参考上一篇文章。在上一篇文章的基础上,nginx 已安装好且已启动,目前是 1.24 版本。
一、平滑升级
Nginx 的平滑升级(热升级)是一种 不中断服务 即可更新 Nginx 版本的核心功能,其设计基于 多进程模型 和 UNIX 信号机制。
上面源码安装的是 1.24 版本的 Nginx,现在到官网下载 1.26 版本 Nginx 做平滑升级实验。
Nginx 官网:www.nginx.org
下载 1.26 版本的 Nginx。
wget https://nginx.org/download/nginx-1.26.3.tar.gz
下载实验会用到的 echo-nginx-module-0.63.tar.gz 模块,因为这个模块在 Nginx 1.26.0 时 echo 模块为了软件精简,把此模块踢除了,所以在这里需要单独下载。
echo-nginx-module-0.63.tar.gz 这个模块用于为 Nginx 服务器提供与 echo 相关的特定功能扩展。具体的功能可能包括但不限于以下几点:
-
增强 Nginx 的输出能力,例如能够更灵活地定制响应的输出内容和格式。
-
可能支持在 Nginx 配置中使用特定的 echo 指令来直接输出某些信息,而无需通过复杂的配置或后端处理。
-
有助于在 Nginx 处理请求和响应的过程中,更方便地添加、修改或展示特定的文本信息。
echo 模块网址:Tags · openresty/echo-nginx-module · GitHub
下载并解压 echo-nginx-module-0.63.tar.gz 模块。
wget https://github.com/openresty/echo-nginx-module/archive/refs/tags/v0.63.tar.gz
tar xzf echo-nginx-module-0.63.tar.gz
解压后生成一个 echo-nginx-module-0.63 目录,编译 Nginx 时要读取这个目录。
解压 nginx-1.26.3。
tar xzf nginx-1.26.3.tar.gz
解压后生成 nginx-1.26.3 目录,进入此目录,检测环境,环境检测内容同上源码编译相同(需要哪个软件安装哪个软件就好)。 注意:此时需要添加 echo-nginx-module-0.63 模块。
./configure \
--prefix=/usr/local/nginx \ # 安装目录
--user=nginx \ # 指定nginx运行用户
--group=nginx \ # 指定nginx运行组
--with-http_ssl_module \ # 支持https://
--with-http_v2_module \ # 支持http版本2
--with-http_realip_module \ # 支持ip透传
--with-http_stub_status_module \ # 支持状态页面
--with-http_gzip_static_module \ # 支持压缩
--with-pcre \ # 支持正则
--with-stream \ # 支持tcp反向代理
--with-stream_ssl_module \ # 支持tcp的ssl加密
--add-module=/root/echo-nginx-module-0.63 #添加外部模块
make 编译(注意:此时不需要 make install),make 会生成 nginx 执行文件和相关信息。
make
把 /usr/local/nginx/sbin/ 目录下的 nginx 文件备份一份。注意:此时此目录下应只有一个 nginx 文件,如果有多的文件,则需要重新 make install 将编译生成的文件安装到指定位置,再备份。
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old
把新版本的执行信息复制到 nginx 的执行目录里。\cp -f 强制覆盖文件,\cp 表示是用的真实的 cp 命令,而不是 alias 里的 cp -i 别名命令(这里的作用是直接覆盖文件,并且系统不提醒)。
\cp -f /root/nginx-1.26.3/objs/nginx /usr/local/nginx/sbin/
查看旧的 nginx 进程号,kill -USER2 重新加载配置文件、启用新的工作进程(只启动进程,不监听端口),以实现平滑升级而不导致服务中断。
ps aux | grep nginx
kill -USR2 35081 # 旧版本的nginx master进程号
此时有两套 nginx 进程,旧的和新的,回收旧的 worker 进程。
kill -WINCH 35081 # 旧版本的nginx master进程号
旧的进程 worker 删除了,master 还在,系统自动将所有的资源分配给了新的 worker。如果确定后续不需要回滚操作,就可以 kill -9 删除 master 进程。
测试:查看此时 nginx 提供服务的版本。
curl -I 192.168.67.100
这里可以看到,以前的版本是 1.24 版本,目前升级了是 1.26 版本。
测试:另一台客户端一直访问次 nginx 服务,证明我们在平滑升级的过程中,nginx 服务从未断过,升级的过程中客户感受不到一点异常。
while true
do
curl 192.168.67.100;sleep 1
done
二、回滚
为什么要回滚:在升级出现问题时,通过发送信号重新启用旧进程并停止新进程,恢复到升级前的状态。
修改 nginx 安装目录下的文件,备份新的 nginx 文件为 nginx.new,还原旧的 nginx 文件。
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.new
\cp -f nginx.old nginx
如果升级的版本发现问题需要回滚,可以重新拉起旧版本的 worker。
kill -HUP 35081 # 旧版本的ginx master进程号
此时激活了旧版本的 worker,再回收新版本的 worker。
kill -WINCH 35087 # 新版本的nginx master进程号
旧的进程 worker 删除了,master 还在,系统自动将所有的资源分配给了新的 worker。
测试:查看此时 nginx 提供服务的版本,版本已恢复旧版本。
curl -I 192.168.67.100
可以看到此时 nginx 的版本已恢复之前的 1.24。
kill -9 删除新的 nginx master 进程。
kill -9 35087 # 新版本的nginx master进程号