nginx 使用 usr1 信号(或 nginx -s reopen)可安全平滑轮转日志:主进程通知工作进程关闭旧日志文件并以绝对路径重新打开新文件,要求日志目录可写、配置路径为绝对路径、操作主进程 pid,并可通过时间戳或 tail 验证切换成功。

在 Nginx 中,使用 USR1 信号可以安全、平滑地完成日志轮转(log rotation),无需重启或重载服务,也不会丢失请求日志。其原理是:Nginx 主进程收到 USR1 后,通知所有工作进程关闭当前打开的日志文件句柄,并重新以配置中指定的路径打开新文件——旧文件可被外部工具归档或压缩,新日志从此时起写入新文件。
前提条件:确保日志路径可写且配置正确
确保以下几点已满足,否则 USR1 会失败或静默忽略:
- Nginx 配置中
access_log和/或error_log使用的是**绝对路径**(相对路径可能因工作目录不一致导致写入异常); - Nginx 工作进程用户(如
www-data或nginx)对日志所在目录有**写权限**; - 日志文件本身不需要手动创建,Nginx 会在收到
USR1后自动新建(但目录必须存在且可写); - 确认你操作的是主进程 ID(PID),不是工作进程——通常 PID 文件位于
/var/run/nginx.pid或通过ps aux | grep nginx查看 master 进程。
发送 USR1 信号的标准方法
推荐使用 nginx -s reopen 命令,它本质就是向主进程发送 USR1,更安全、可读性高:
sudo nginx -s reopen
等价的手动方式(需先获取主进程 PID):
sudo kill -USR1 $(cat /var/run/nginx.pid)
如果 PID 文件位置不同,请替换为实际路径(如 /usr/local/nginx/logs/nginx.pid)。
验证日志是否已切换成功
执行后可通过以下方式快速确认:
- 检查旧日志文件的最后修改时间:
ls -l /var/log/nginx/access.log,再运行reopen后应变为“几分钟前”,而新文件开始写入; - 用
ls -lt /var/log/nginx/查看最新生成的access.log是否时间戳更新; - 用
tail -f /var/log/nginx/access.log观察是否有新访问日志实时写入(说明新文件已激活); - 检查 Nginx 错误日志(
error.log)中是否出现reopening logs提示(默认级别 info 可见)。
配合 logrotate 实现自动化轮转
生产环境通常用 logrotate 管理日志,只需在其配置中添加 postrotate 段调用 reopen:
/var/log/nginx/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 0644 www-data www-data
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
invoke-rc.d nginx rotate || true
fi
endscript
}
注意:invoke-rc.d nginx rotate 是 Debian/Ubuntu 的封装命令,等效于 nginx -s reopen;CentOS/RHEL 可直接写 nginx -s reopen。











