必须用 SIGUSR1 因其是专为日志管理设计的“软重开”机制,不中断请求、不影响 worker 进程,仅让主进程重读日志路径并通知 worker 切换至新文件写入。

为什么必须用 SIGUSR1 而不是重启或重载
Nginx 的 SIGUSR1 信号是专为日志管理设计的“软重开”机制。它不会中断任何请求,也不影响 worker 进程处理流量,只是让主进程重新读取配置中 access_log 和 error_log 指定的路径,然后以当前用户身份创建新文件,并通知所有 worker 进程切换到新文件写入。相比之下:
– kill -HUP(重载配置)会触发完整 reload,可能短暂影响连接;
– systemctl restart nginx 会造成服务中断;
– 直接 mv 日志后不发信号,worker 进程仍往已移动的旧文件句柄写入,导致日志丢失且磁盘空间无法释放。
手动执行一次完整滚动流程
适合验证逻辑或临时操作,步骤清晰、无依赖:
- 先确认 Nginx 主进程 PID 文件位置,例如:
/usr/local/nginx/logs/nginx.pid(路径需与配置一致) - 获取昨日日期并重命名日志:
yesterday=$(date -d "yesterday" +%Y-%m-%d)mv /usr/local/nginx/logs/access.log /usr/local/nginx/logs/access_${yesterday}.logmv /usr/local/nginx/logs/error.log /usr/local/nginx/logs/error_${yesterday}.log - 发送 USR1 信号:
kill -USR1 $(cat /usr/local/nginx/logs/nginx.pid) - 检查是否生成新空日志:
ls -l /usr/local/nginx/logs/access.log应存在且大小为 0 - 旧日志此时可压缩或归档,例如:
gzip /usr/local/nginx/logs/access_${yesterday}.log
用 logrotate 实现全自动按天滚动
这是生产环境最推荐的方式,稳定、可配置、自带压缩与清理策略。将以下内容写入 /etc/logrotate.d/nginx:
/usr/local/nginx/logs/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 0644 nginx nginx
sharedscripts
postrotate
if [ -f /usr/local/nginx/logs/nginx.pid ]; then
kill -USR1 $(cat /usr/local/nginx/logs/nginx.pid)
fi
endscript
}
关键点说明:
– daily 表示每天零点触发(由系统 cron 调用);
– rotate 30 保留最近 30 个归档,超出自动删除;
– delaycompress 确保刚切割的日志不立即压缩,方便排查当日问题;
– create 0644 nginx nginx 保证新日志权限和属主正确,避免因权限问题写入失败;
– sharedscripts + postrotate 确保整个日志组只发一次 USR1,而非每个文件都触发。
验证与排错要点
常见问题往往出在路径、权限或信号接收环节:
- 检查
nginx.pid是否存在且内容为有效数字;路径需与 Nginx 启动时-p或配置中pid指令一致 - 确认运行 logrotate 的用户(通常是 root)有权限读取
nginx.pid并向对应 PID 发信号 - 执行
logrotate -d /etc/logrotate.d/nginx可模拟运行并输出详细过程(-d 是 debug 模式) - 观察日志文件时间戳:新
access.log修改时间应在 USR1 执行后更新;旧文件不应再增长 - 若日志仍在原文件追加,大概率是 USR1 未成功发送,可用
strace -p $(cat nginx.pid) -e trace=signal抓取信号接收情况


















