Controlling nginx

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

Note

TERM, INTfast shutdown
QUITgraceful shutdown
HUP更改配置,紧跟更改的时区(仅适用于 FreeBSD 和 Linux),使用新配置启动新工作进程,正常关闭旧工作进程
USR1重新打开日志文件
USR2升级可执行文件
WINCH正常关闭工作进程

尽管不是必需的,但是也可以通过 signal 控制单个工作进程。支持的 signal 是:

Note

TERM, INTfast shutdown
QUITgraceful shutdown
USR1重新打开日志文件
WINCH异常终止以进行调试(需要启用debug_points)

Changing Configuration

为了使 nginx 重新读取配置文件,应将 HUPsignal 发送到主进程。主进程首先检查语法的有效性,然后尝试应用新的配置,即打开日志文件和新的侦听套接字。如果失败,它将回滚更改并 continue 使用旧配置。如果成功,它将启动新的工作进程,并将消息发送到旧的工作进程,要求它们正常关闭。老 Worker 进程关闭监听套接字,并 continue 为老客户提供服务。为所有客户端提供服务后,将关闭旧的工作进程。

让我们通过示例进行说明。想象一下 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 的旧工作进程之一仍然可以 continue 工作。一段时间后,它退出:

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)

Rotating Log-files

为了轮转日志文件,需要首先将其重命名。之后,USR1signal 应发送到主进程。然后,主进程将重新打开所有当前打开的日志文件,并为它们分配一个运行工作进程的未特权用户,作为所有者。成功重新打开后,主进程将关闭所有打开的文件,并将消息发送给工作进程,以要求它们重新打开文件。辅助进程还会立即打开新文件并关闭旧文件。结果,旧文件几乎可以立即用于压缩等后处理。

即时升级可执行文件

为了升级服务器可执行文件,应首先将新的可执行文件替换旧文件。之后,USR2signal 应发送到主进程。主进程首先将其具有进程 ID 的文件重命名为带有.oldbin后缀的新文件,例如/usr/local/nginx/logs/nginx.pid.oldbin,然后启动一个新的可执行文件,该文件又启动新的工作进程:

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)

之后,所有工作进程(旧的和新的)continue 接受请求。如果 WINCHsignal 发送到第一个主进程,它将向其工作进程发送消息,要求它们正常关闭,然后它们将开始退出:

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)

应当注意,旧的主进程不会关闭其侦听套接字,并且可以根据需要对其进行管理以再次启动其工作进程。如果由于某种原因新的可执行文件无法正常工作,则可以执行以下操作之一:

  • 将 HUPsignal 发送到旧的主进程。旧的主进程将启动新的工作进程,而无需重新读取配置。之后,可以通过将 QUITsignal 发送到新的主进程来正常关闭所有新进程。

  • 将 TERMsignal 发送到新的主进程。然后它将向其工作进程发送一条消息,要求它们立即退出,并且它们几乎都将立即退出。 (如果新进程由于某种原因未退出,则应向其发送 KILLsignal 以强制其退出.)当新的主进程退出时,旧的主进程将自动启动新的工作进程。

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

如果升级成功,则应该将 QUIT signal 发送到旧的主进程,而只有新进程会保留:

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)