Nginx 控制

本文将介绍怎样通过发送信号去控制 nginx,在 linux 中我们可以通过 kill 命令发送信号给 nginx,这个使用 nginx -s 类似。

在开始介绍控制Nginx之前,我们先使用“ps -ef | grep nginx”查看一下 nginx 的进程。如下:

[root@S0 ~]# ps -ef | grep nginx
root     21325     1  0 02:21 ?        00:00:00 nginx: master process ./nginx
nobody   23598 21325  0 02:42 ?        00:00:00 nginx: worker process
root     23714 23698  0 22:26 pts/0    00:00:00 grep nginx

从上得知,我们有一个主nginx进程(master process),主进程不负责处理用户请求;还有一个工作进程(worker process),该进程数量与我们在 nginx.conf 中配置的 worker_processes 有关,该进程才真实处理用户请求。

Nginx可以用信号控制。默认情况下,主进程的进程ID被写入文件 /usr/local/nginx/log/nginx.pid。此名称可以在配置时更改,也可以在 nginx.conf 中使用 PID 指令更改。主进程支持以下信号:

  • TERM, INT:快速关闭,即使当前有请求正在处理,也立刻关闭nginx。

  • QUIT:优雅的关闭,等待当前正在处理的请求完成后才关闭nginx。 

  • HUP:更改配置,保持更改的时区(仅适用于FreeBSD和Linux),使用新配置启动新工作进程,优雅地关闭旧工作进程。   

  • USR1:重新打开日志文件。

  • USR2:更新可执行文件,即 nginx 文件。

  • WINCH:优雅地关闭工作进程。

单独的工作进程也可以用信号来控制,尽管这不是必需的。所支持的信号为:

  • TERM, INT:快速关闭,即使当前有请求正在处理,也立刻关闭当前进程。

  • QUIT:优雅的关闭,等待当前正在处理的请求完成后才关闭当前进程。 

  • USR1:重新打开日志文件。

  • WINCH:调试异常终止(需要启用debug_points)。

改变配置

为了让 nginx 重新读取配置文件,应该向主进程发送 HUP 信号。主进程首先检查语法有效性,然后尝试应用新的配置,即打开日志文件和新的监听套接字。如果失败,它将回滚更改并继续使用旧的配置。如果成功,它将启动新的 worker 进程,并向旧的worker进程发送消息,请求它们优雅地关闭。旧工作进程关闭监听套接字并继续为老客户端提供服务。在所有客户端都得到服务之后,旧工作进程才会被关闭。

让我们用例子来说明这一点。假设 nginx 在 FreeBSD 上运行命令:

ps axw -o pid,ppid,user,%cpu,vsz,wchan,command | egrep '(nginx|PID)'

产生以下输出:

  PID  PPID USER    %CPU   VSZ WCHAN  COMMAND
33126     1 root     0.0  1148 pause  nginx: master process /usr/local/nginx/sbin/nginx
33127 33126 nobody   0.0  1380 kqread nginx: worker process (nginx)
33128 33126 nobody   0.0  1364 kqread nginx: worker process (nginx)
33129 33126 nobody   0.0  1364 kqread nginx: worker process (nginx)

如果 HUP 发送到主进程,输出为:

  PID  PPID USER    %CPU   VSZ WCHAN  COMMAND
33126     1 root     0.0  1164 pause  nginx: master process /usr/local/nginx/sbin/nginx
33129 33126 nobody   0.0  1380 kqread nginx: worker process is shutting down (nginx)
33134 33126 nobody   0.0  1368 kqread nginx: worker process (nginx)
33135 33126 nobody   0.0  1368 kqread nginx: worker process (nginx)
33136 33126 nobody   0.0  1368 kqread nginx: worker process (nginx)

使用 PID 33129 的一个旧工作进程仍然在工作。一段时间后,它退出:

  PID  PPID USER    %CPU   VSZ WCHAN  COMMAND
33126     1 root     0.0  1164 pause  nginx: master process /usr/local/nginx/sbin/nginx
33134 33126 nobody   0.0  1368 kqread nginx: worker process (nginx)
33135 33126 nobody   0.0  1368 kqread nginx: worker process (nginx)
33136 33126 nobody   0.0  1368 kqread nginx: worker process (nginx)

转储日志文件

为了转储日志文件,首先需要重命名它们。之后应该发送 USR1 信号到主进程(master进程)。然后,主进程将重新打开所有当前打开的日志文件,并将它们分配给一个非特权用户 (worker进程在该用户下作为所有者运行)。成功重新打开后,主进程关闭所有打开的文件,并向 worker 进程发送消息,要求它们重新打开文件。工作进程打开新文件并立即关闭旧文件。因此,旧文件几乎可以立即用于后期处理,比如压缩。

动态升级可执行文件

为了升级服务器的可执行文件(即 nginx 二进制文件),应该先用新的可执行文件替换旧的文件(建议将旧的nginx可执行文件进行备份,如:nginx.old)。之后,应该发送 USR2 信号到主进程(USR2:更新可执行文件)。主进程首先用进程 ID 将其文件重命名为一个后缀为 .oldbin 的新文件,例如 /usr/local/nginx/logs/nginx.pid.oldbin。然后启动新的可执行文件(新的PID位于 ningx.pid 文件中),启动新的工作进程:

  PID  PPID USER    %CPU   VSZ WCHAN  COMMAND
33126     1 root     0.0  1164 pause  nginx: master process /usr/local/nginx/sbin/nginx
33134 33126 nobody   0.0  1368 kqread nginx: worker process (nginx)
33135 33126 nobody   0.0  1380 kqread nginx: worker process (nginx)
33136 33126 nobody   0.0  1368 kqread nginx: worker process (nginx)
36264 33126 root     0.0  1148 pause  nginx: master process /usr/local/nginx/sbin/nginx
36265 36264 nobody   0.0  1364 kqread nginx: worker process (nginx)
36266 36264 nobody   0.0  1364 kqread nginx: worker process (nginx)
36267 36264 nobody   0.0  1364 kqread nginx: worker process (nginx)

之后,所有工作进程(旧进程和新进程)继续接受请求。如果 WINCH 信号被发送到第一个主进程(旧的主进程),它将向它的工作进程发送消息,请求它们优雅地关闭,它们将开始退出:

  PID  PPID USER    %CPU   VSZ WCHAN  COMMAND
33126     1 root     0.0  1164 pause  nginx: master process /usr/local/nginx/sbin/nginx
33135 33126 nobody   0.0  1380 kqread nginx: worker process is shutting down (nginx)
36264 33126 root     0.0  1148 pause  nginx: master process /usr/local/nginx/sbin/nginx
36265 36264 nobody   0.0  1364 kqread nginx: worker process (nginx)
36266 36264 nobody   0.0  1364 kqread nginx: worker process (nginx)
36267 36264 nobody   0.0  1364 kqread nginx: worker process (nginx)

一段时间后,只有新工作进程在处理请求:

  PID  PPID USER    %CPU   VSZ WCHAN  COMMAND
33126     1 root     0.0  1164 pause  nginx: master process /usr/local/nginx/sbin/nginx
36264 33126 root     0.0  1148 pause  nginx: master process /usr/local/nginx/sbin/nginx
36265 36264 nobody   0.0  1364 kqread nginx: worker process (nginx)
36266 36264 nobody   0.0  1364 kqread nginx: worker process (nginx)
36267 36264 nobody   0.0  1364 kqread nginx: worker process (nginx)

应该注意的是,旧的主进程并没有被关闭,它依然能够监听套接字。如果需要,可以管理它重新启动工作进程。如果由于某种原因,新的可执行文件不能接受请求,可以采取以下措施之一:

  • 向旧主进程发送HUP信号。旧主进程将启动新的工作进程,而无需重新读取配置。然后,通过向新主进程发送 QUIT 信号,可以优雅地关闭所有新进程。

  • 向新主进程发送 TERM 信号。然后,它将向其工作进程发送一条消息,请求它们立即退出,它们几乎都将立即退出。(如果新进程由于某种原因没有退出,则应该向它们发送 KILL 信号,迫使它们退出) 当新的主进程退出时,旧的主进程将自动启动新的工作进程。

如果新的主进程退出,那么旧的主进程将从带有进程 ID 的文件名中丢弃 .oldbin 后缀。

如果升级成功,则 QUIT 信号应发送到旧主进程,只保留新进程:

  PID  PPID USER    %CPU   VSZ WCHAN  COMMAND
36264     1 root     0.0  1148 pause  nginx: master process /usr/local/nginx/sbin/nginx
36265 36264 nobody   0.0  1364 kqread nginx: worker process (nginx)
36266 36264 nobody   0.0  1364 kqread nginx: worker process (nginx)
36267 36264 nobody   0.0  1364 kqread nginx: worker process (nginx)
如果在胜利前却步,往往只会拥抱失败;如果在困难时坚持,常常会获得新的成功。
0 不喜欢
说说我的看法 -
全部评论(
没有评论
关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号