如何在不中断客户端连接的情况下就地升级 Nginx

介绍

Nginx 是一个强大的 Web 服务器和反向代理,用于服务世界上许多最受欢迎的网站. 在本指南中,我们将展示如何升级 Nginx 可执行程序,而不会失去客户端连接。

前提条件

在开始本指南之前,您应该在您的服务器上有一个非根用户,配置有sudo权限。

您可以遵循 Ubuntu 22.04 的初始服务器设置指南(https://andsky.com/tech/tutorials/initial-server-setup-with-ubuntu-22-04),然后在该服务器上安装 Nginx(https://andsky.com/tech/tutorials/how-to-install-nginx-on-ubuntu-22-04)。

如何升级工作

Nginx 通过在服务启动时生成主流程来工作. 主流服务反过来,生成一个或多个处理实际客户端连接的工人流程. Nginx 旨在在从系统接收特定低级别信号时执行某些操作。

Nginx提供的安装和升级脚本旨在在在启动、停止和重新启动 Nginx 时发送这些信号,但是,手动发送这些信号允许您在出现问题时快速审核升级并恢复更新。

将使用以下信号:

  • USR2:这会产生一组新的主/工人流程,而不会影响旧的集合。
  • WINCH:这会告诉 Nginx 主流程以优雅的方式阻止其相关的工人实例。
  • HUP:这会告诉 Nginx 主流流程重新读取其配置文件并用遵循新配置的工人流程替换。如果一个旧和新的主流正在运行,将此发送给旧主流会使工人使用其原始配置。

寻找 Nginx 流程 PID

为了向各个进程发送信号,我们需要知道目标进程的PID。

首先,您可以使用ps实用程序,然后在结果中抓住 Nginx。

1ps aux | grep nginx
1[secondary_label output]
2root 16653 0.0 0.2 119160 2172 ?        Ss 21:48 0:00 nginx: master process /usr/sbin/nginx
3nginx 16654 0.0 0.9 151820 8156 ?        S 21:48 0:00 nginx: worker process
4sammy 16688 0.0 0.1 221928 1164 pts/0 S+   21:48 0:00 grep --color=auto nginx

第二列包含所选进程的PID,最后一列澄清了第一个结果是 Nginx 主进程。

找到主 Nginx 流程的 PID 的另一种方法是打印 /run/nginx.pid 文件的内容:

1cat /run/nginx.pid
1[secondary_label output]
216653

如果有两个 Nginx 主流程正在运行,则旧流程将移动到 `/run/nginx.pid.oldbin。

创建一个新的 Nginx 主人 / 工人集

优雅地更新的第一步是实际更新您的 Nginx 包和 / 或二进制. 使用任何适合您的 Nginx 安装的方法,无论是通过包管理器或源安装。

一旦新的二进制处于位置,您可以生成使用新执行程序的第二组主/工人流程。

您可以通过将USR2信号直接发送到您所查询的PID号码(请在此处替换您自己的Nginx主流程的PID):

1sudo kill -s USR2 16653

或者,您可以将存储在 PID 文件中的值直接读入命令中,如下:

1sudo kill -s USR2 `cat /run/nginx.pid`

如果你检查你的运行过程,你会看到你现在有两个 Nginx 大师和工人:

1ps aux | grep nginx
1[secondary_label output]
2root 16653 0.0 0.2 119160 2172 ?        Ss 21:48 0:00 nginx: master process /usr/sbin/nginx
3nginx 16654 0.0 0.9 151820 8156 ?        S 21:48 0:00 nginx: worker process
4root 16699 0.0 1.5 119164 12732 ?        S 21:54 0:00 nginx: master process /usr/sbin/nginx
5nginx 16700 0.0 0.9 151804 8008 ?        S 21:54 0:00 nginx: worker process
6sammy 16726 0.0 0.1 221928 1148 pts/0 R+   21:55 0:00 grep --color=auto nginx

您还可以看到原始 /run/nginx.pid 文件已移动到 /run/nginx.pid.oldbin 和较新的主流程的 PID 已写到 /run/nginx.pid:

1tail -n +1 /run/nginx.pid*
1[secondary_label output]
2==> /run/nginx.pid <==
316699
4
5==> /run/nginx.pid.oldbin <==
616653

您现在可以使用这些文件中包含的 PID 向任何一个主流程发送信号。

在这一点上,两个主/工人集都是操作的,能够服务客户端的请求. 第一组使用原始的 Nginx 可执行和配置,第二组使用更新的版本. 它们可以继续运作,但为了一致性,我们应该开始过渡到新集。

关闭第一大师的工人

为了开始向新集的过渡,首先要做的是停止原始大师的工人流程,原始工人将完成处理所有当前的连接,然后退出。

通过向他们的主流程发出WINCH信号来阻止原始集的工人:

1sudo kill -s WINCH `cat /run/nginx.pid.oldbin`

这将允许新主人的员工单独处理新客户端连接,旧的 master 过程仍在运行,但没有员工:

1ps aux | grep nginx
1[secondary_label output]
2root 16653 0.0 0.2 119160 2172 ?        Ss 21:48 0:00 nginx: master process /usr/sbin/nginx
3root 16699 0.0 1.5 119164 12732 ?        S 21:54 0:00 nginx: master process /usr/sbin/nginx
4nginx 16700 0.0 0.9 151804 8008 ?        S 21:54 0:00 nginx: worker process
5sammy 16755 0.0 0.1 221928 1196 pts/0 R+   21:56 0:00 grep --color=auto nginx

这允许您对新员工进行审计,因为他们在孤立中接受连接。

评估结果并采取下一步

您应该在这一点上测试和审核您的系统,以确保没有任何问题迹象. 您可以让您的配置处于这种状态,只要您希望确保新的 Nginx 可执行程序是无错误的,可以处理您的流量。

你的下一步将完全取决于你是否遇到问题。

如果你的升级成功了

如果你没有遇到新集的工作人员的问题,你可以安全地关闭旧主流程. 要做到这一点,发送旧主人的QUIT信号:

1sudo kill -s QUIT `cat /run/nginx.pid.oldbin`

旧主流程将顺利退出,只留下您新的一组 Nginx 主/工人. 在此时刻,您已经成功地执行了 Nginx 的现场二进制更新,而无需中断客户端连接。

如果你的升级失败了

如果你的新员工似乎有问题,你可以回到旧的配置和二进制。

最好的方法是通过发送HUP信号来重新启动你的老大师的工人。通常,当你发送一个Nginx大师的HUP信号时,它会重新阅读其配置文件并启动新的工人。

1sudo kill -s HUP `cat /run/nginx.pid.oldbin`

您现在应该恢复到两组主 / 工人流程:

1ps aux | grep nginx
1[secondary_label output]
2root 16653 0.0 0.2 119160 2172 ?        Ss 21:48 0:00 nginx: master process /usr/sbin/nginx
3nginx 16654 0.0 0.9 151820 8156 ?        S 21:48 0:00 nginx: worker process
4root 16699 0.0 1.5 119164 12732 ?        S 21:54 0:00 nginx: master process /usr/sbin/nginx
5nginx 16700 0.0 0.9 151804 8008 ?        S 21:54 0:00 nginx: worker process
6sammy 16726 0.0 0.1 221928 1148 pts/0 R+   21:55 0:00 grep --color=auto nginx

最新的工人与老大师有关联,两组工人将此时接受客户端连接,现在通过发送QUIT信号来阻止更新的、buggy master 流程及其工人:

1sudo kill -s QUIT `cat /run/nginx.pid`

你应该回到你的老主人和工人:

1ps aux | grep nginx
1[secondary_label output]
2root 16653 0.0 0.2 119160 2172 ?        Ss 21:48 0:00 nginx: master process /usr/sbin/nginx
3nginx 16654 0.0 0.9 151820 8156 ?        S 21:48 0:00 nginx: worker process
4sammy 16688 0.0 0.1 221928 1164 pts/0 S+   21:48 0:00 grep --color=auto nginx

原始主将恢复其 PID 的 /run/nginx.pid 文件。

如果这不起作用,你可以尝试只发送新的主服务器的TERM信号,这应该启动关闭。这应该阻止新的主人和任何工人,同时自动跳过旧的主人启动其工人流程。如果有严重的问题,而错误的工人没有退出,你可以发送他们每一个KILL信号清理。这应该是最后的手段,然而,因为它将切断连接。

过渡到旧的二进制后,请记住,您仍然在您的系统上安装了新版本. 您应该删除错误的版本,然后滚回以前的版本,以便 Nginx 在重新启动时运行无问题。

结论

到目前为止,您应该能够无缝地将您的机器从一个 Nginx 二进制转移到另一个 Nginx 的能力来处理两个大师 / 工人集,同时保持有关他们的关系的信息,使我们能够升级服务器软件而不将服务器机器脱机。

Published At
Categories with 技术
Tagged with
comments powered by Disqus