根本原因是 logrotate 默认 reload 触发全量重载,应改用 USR1 信号(systemd)或 -s reopen(init.d)实现毫秒级日志重开;需修改 /www/server/panel/vhost/logrotate/nginx 中 postrotate 行,禁用 service/nginx -s reload,验证时检查 worker PID 不变且无权限错误。

为什么 logrotate 切割网站日志时 Nginx 会卡住重启?
根本原因是默认的 logrotate 配置在 rotate 后执行 nginx -s reload 或 systemctl reload nginx,而宝塔面板生成的配置里常混用 invoke-rc.d、service 或直接调用二进制,这些方式在高并发或模块加载多(如 Lua、ModSecurity)时容易阻塞在信号处理或 worker 进程退出阶段,表现为 reload 耗时 3–10 秒甚至超时失败。
如何修改 /www/server/panel/vhost/logrotate/nginx 中的 reload 行?
宝塔的站点日志切割逻辑由该文件控制,关键要避开「全量 reload」,改用更轻量、可预测的重载方式。需确认当前 Nginx 启动方式(systemd 还是 init.d),再针对性替换:
- 若用 systemd(宝塔 7.9+ 默认):把原
reload行替换成/bin/systemctl kill --signal=USR1 nginx—— USR1 是 Nginx 原生支持的「重新打开日志文件」信号,不触发 worker 重启,毫秒级完成 - 若仍用 init.d(老版本或自定义编译):替换为
/www/server/nginx/sbin/nginx -s reopen,效果等同 USR1,且不依赖系统服务管理器 - 绝对不要写
service nginx reload或nginx -s reload—— 它们会触发完整配置校验 + worker 平滑切换,是慢的根源
logrotate 配置中哪些参数会影响 reload 行为?
logrotate 自身不决定 reload 方式,但以下参数会间接放大问题:
-
delaycompress:启用后旧日志压缩被延迟到下一轮,意味着postrotate阶段可能还在写入旧文件,此时 reload 容易冲突 → 建议关闭,或确保compress和delaycompress不共存 -
sharedscripts:若多个站点日志共用一个配置块,它会让postrotate只执行一次 —— 但宝塔默认按站点拆分配置,一般不启用,不必动 -
create 644 www www:必须保留,否则新日志权限错误会导致 Nginx 写入失败,进而触发后续 reload 异常
真正起效的是你手动改写的 postrotate 段落,例如:
/www/wwwroot/example.com/*.log {
daily
missingok
rotate 30
compress
notifempty
create 644 www www
sharedscripts
postrotate
/bin/systemctl kill --signal=USR1 nginx 2>/dev/null || true
endscript
}
验证是否生效及常见失败点
改完配置后必须手动触发一次测试:logrotate -f /www/server/panel/vhost/logrotate/nginx,然后观察:
- 检查
ps aux | grep nginx:worker 进程 PID 应完全不变,master 进程时间戳更新即可 - 查 Nginx 错误日志:
tail -n 10 /www/server/nginx/logs/error.log,不应出现open() "/www/wwwroot/example.com/access.log" failed (13: Permission denied)或invalid PID number - 最易踩坑的是 SELinux 或安全模块拦截
USR1信号 —— 若 reload 无声无息没反应,先临时setenforce 0测试,确认后再配策略
注意:宝塔升级可能覆盖该文件,建议备份修改后的版本,并在升级后快速比对 diff。


















