title: 控制nginx
cover: https://res.ciduid.top/blog/covers/cover(8).jpg
date: 2022-08-06 16:52:03
---

## Controlling nginx

[修改配置 Changing Configuration](https://nginx.org/en/docs/control.html#reconfiguration)  

[日志切割 Rotating Log-files](https://nginx.org/en/docs/control.html#logs)  

[热更新 Upgrading Executable on the Fly](https://nginx.org/en/docs/control.html#upgrade)

nginx can be controlled with signals. The process ID of the master process is written to the file `/usr/local/nginx/logs/nginx.pid` by default. This name may be changed at configuration time, or in `nginx.conf` using the [pid](https://nginx.org/en/docs/ngx_core_module.html#pid) directive. The master process supports the following signals:

nginx可以用信号来控制，nginx主进程ID默认写在`/usr/local/nginx/logs/nginx.pid`文件中。这个文件的位置可以在编译配置的时候指定，或者在`nginx.conf`中使用[pid](https://nginx.org/en/docs/ngx_core_module.html#pid)指令指定。

主进程支持以下信号的控制

> | | |
> | --- | --- |
> | TERM, INT | fast shutdown |
> | QUIT      | graceful shutdown |
> | HUP       | changing configuration, keeping up with a changed time zone (only for FreeBSD and Linux), starting new worker processes with a new configuration, graceful shutdown of old worker processes |
> | USR1      | re-opening log files |
> | USR2      | upgrading an executable file |
> | WINCH     | graceful shutdown of worker processes |

> | | |
> | --- | --- |
> | TERM, INT | 快速关闭 |
> | QUIT      | 平稳关闭 |
> | HUP       | 用于一般用于配置文件更改，修改时区（仅适用于FreeBSD和Linux）时使用，用新的配置启动新的worker进程，平稳关闭旧的worker进程 |
> | USR1      | 重新打开日志文件 |
> | USR2      | 升级可执行文件 |
> | WINCH     | 平稳关闭worker进程 |

Individual worker processes can be controlled with signals as well, though it is not required. The supported signals are:

单个worker进程也能用信号来控制，不过这不是必须的

支持的信号有

> | | | 
> | --- | --- |
> | TERM, INT | fast shutdown |
> | QUIT      | graceful shutdown |
> | USR1      | re-opening log files |
> | WINCH     | abnormal termination for debugging (requires [debug_points](https://nginx.org/en/docs/ngx_core_module.html#debug_points) to be enabled) |

> | | |
> | --- | --- |
> | TERM, INT | 快速关闭 |
> | QUIT      | 平稳关闭 |
> | USR1      | 重新打开日志文件 |
> | WINCH     | 用于调试的非正常终止 (需要启用[debug_points](https://nginx.org/en/docs/ngx_core_module.html#debug_points)) |

#### Changing Configuration

In order for nginx to re-read the configuration file, a HUP signal should be sent to the master process. The master process first checks the syntax validity, then tries to apply new configuration, that is, to open log files and new listen sockets. If this fails, it rolls back changes and continues to work with old configuration. If this succeeds, it starts new worker processes, and sends messages to old worker processes requesting them to shut down gracefully. Old worker processes close listen sockets and continue to service old clients. After all clients are serviced, old worker processes are shut down.

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

Let’s illustrate this by example. Imagine that nginx is run on FreeBSD and the command

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

produces the following output:

>   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)

If HUP is sent to the master process, the output becomes:

>   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)

One of the old worker processes with PID 33129 still continues to work. After some time it exits:

>   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

In order to rotate log files, they need to be renamed first. After that USR1 signal should be sent to the master process. The master process will then re-open all currently open log files and assign them an unprivileged user under which the worker processes are running, as an owner. After successful re-opening, the master process closes all open files and sends the message to worker process to ask them to re-open files. Worker processes also open new files and close old files right away. As a result, old files are almost immediately available for post processing, such as compression.

#### Upgrading Executable on the Fly

In order to upgrade the server executable, the new executable file should be put in place of an old file first. After that USR2 signal should be sent to the master process. The master process first renames its file with the process ID to a new file with the `.oldbin` suffix, e.g. `/usr/local/nginx/logs/nginx.pid.oldbin`, then starts a new executable file that in turn starts new worker processes:

>   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)

After that all worker processes (old and new ones) continue to accept requests. If the WINCH signal is sent to the first master process, it will send messages to its worker processes, requesting them to shut down gracefully, and they will start to exit:

>   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)

After some time, only the new worker processes will process requests:

>   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)

It should be noted that the old master process does not close its listen sockets, and it can be managed to start its worker processes again if needed. If for some reason the new executable file works unacceptably, one of the following can be done:

- Send the HUP signal to the old master process. The old master process will start new worker processes without re-reading the configuration. After that, all new processes can be shut down gracefully, by sending the QUIT signal to the new master process.

- Send the TERM signal to the new master process. It will then send a message to its worker processes requesting them to exit immediately, and they will all exit almost immediately. (If new processes do not exit for some reason, the KILL signal should be sent to them to force them to exit.) When the new master process exits, the old master process will start new worker processes automatically.

If the new master process exits then the old master process discards the `.oldbin` suffix from the file name with the process ID.

If upgrade was successful, then the QUIT signal should be sent to the old master process, and only new processes will stay:

>   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)
