管理nginx
- 改变配置
- 轮替log文件
- 在线更新可执行文件(无须退出当前流程)
nginx能被一些信号管理. 主进程ID默认被写到 /usr/local/nginx/logs/nginx.pid . 这个名字可以在 nginx.conf 中使用 pid 指令来改变. 主进程支持以下的信号:
TERM, INT 快速关闭
QUIT 正常关闭
HUP 重新开启(开启新的工作进程, 正常关闭旧的工作进程)
USR1 重新打开log文件
USR2 更新可执行文件
WINCH 正常关闭工作进程
改变配置
为了让nginx重新读取配置文件, HUP
信号需发送给主进程. 主进程首先检查语法的正确性,然后尝试应用在其配置中. 如果成功, 主进程将开启新的工作进程, 并发送信息给老的工作进程, 要求它们关闭. 否则, 主进程回滚改变的配置以及继续用老的配置工作. 老的工作进程一旦接收到关闭命令, 将停止接收新的请求连接但是会继续服务当前正在处理的请求直到这些请求处理完. 之后, 老的工作进程就会退出.
轮替log文件
为了轮替(分隔)log文件, 首先需要先更改log文件的名称, 然后发送USR1
信号给主进程. 主进程将重新打开所有当前打开的log文件, 并把它们分配给正在运行的工作进程下的未经授权的用户, 作为它们的拥有者. 分配成功之后, 主进程关闭所有打开的log文件, 以及发送信息让工作进程重新打开log文件. 这个时候工作进程打开新的log文件, 以及关闭旧的log文件.
#!/bin/bash
## 零点执行该脚本
## Nginx 日志文件所在的目录
LOGS_PATH=/usr/local/nginx/logs
## 获取昨天的 yyyy-MM-dd
YESTERDAY=\$(date -d ”yesterday” +%Y-%m-%d)
## 移动文件
mv ${LOGS_PATH}/access.log ${LOGS_PATH}/access_${YESTERDAY}.log
## 向 Nginx 主进程发送 USR1 信号。USR1 信号是重新打开日志文件
kill -USR1 \$(cat /usr/local/nginx/nginx.pid)
通过定时执行上面的脚本, 即可分隔log文件, 避免log文件过大
0 0 * * * /bin/bash /usr/local/nginx/sbin/cut-log.sh
在线更新可执行文件
为了更新server执行文件, 首先需要把新的可执行文件放在旧文件的目录下, 然后发送USR2
信号给主进程. 主进程将把进程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)
之后, 所有工作进程(旧的和新的)都继续接收请求, 如果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)
应该注意的是旧的主进程没有关闭它监听的sockets, 因此如果需要, 此主进程可重新开启它的工作进程. 如果因为一些原因, 新的可执行文件不能工作, 那么可以进行下面的操作:
* 发送HUP
信号给旧的主进程, 重新开启工作进程而不需要重新读取配置, 然后发送QUIT
信号给新的主进程, 平滑关闭新的进程.
* 发送TERM
信号给新的主进程, 它将让其工作进程立即退出( 如果因为一些原因没有退出, 可以通过KILL
信号强制退出 ). 当新的主进程退出, 那么旧的主进程将立即开启其工作进程.
如果新的主进程退出, 那么旧的主进程将丢弃.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)