关键是要在nginx.service中配置ExecStop=/usr/local/nginx/sbin/nginx -s quit,确保systemctl stop nginx触发优雅退出;需配合Type=forking、正确PIDFile路径及daemon-reload生效。

源码安装的 Nginx 默认不自带 systemd 服务文件,要实现 systemctl stop nginx 触发优雅停机,关键不是改 Nginx 本身,而是补全并正确配置 nginx.service 单元文件,使其调用 nginx -s quit 而非粗暴 kill。
手动创建标准 nginx.service 文件
源码安装后,Nginx 二进制通常在 /usr/local/nginx/sbin/nginx,需创建对应的服务单元:
- 新建文件:
/etc/systemd/system/nginx.service - 内容至少包含以下核心段(路径、用户、权限请按实际调整):
[Unit] Description=The NGINX HTTP Server After=network.target [Service] Type=forking PIDFile=/usr/local/nginx/logs/nginx.pid ExecStart=/usr/local/nginx/sbin/nginx ExecReload=/usr/local/nginx/sbin/nginx -s reload ExecStop=/usr/local/nginx/sbin/nginx -s quit KillMode=process TimeoutStopSec=30 Restart=on-failure User=root Group=root [Install] WantedBy=multi-user.target
注意:Type=forking 适配 Nginx 主从进程模型;ExecStop 必须指向 -s quit,这是优雅退出的唯一入口。
确保 Nginx 自身支持并启用 quit 机制
源码编译无需额外开关,默认就支持 nginx -s quit。但需验证两点:
- 执行
sudo /usr/local/nginx/sbin/nginx -t确保配置无误,否则quit可能失败 - 确认
pid文件路径与nginx.conf中pid指令一致(如pid logs/nginx.pid;),且路径可读写 - 手动测试:
sudo /usr/local/nginx/sbin/nginx -s quit后,观察ps aux | grep nginx—— 主进程立即消失,worker 进程几秒内自然退出,无残留
启用服务并重载 systemd 配置
创建完 service 文件后,必须让 systemd 重新加载识别:
-
sudo systemctl daemon-reload(必需!否则 systemctl 不认新文件) -
sudo systemctl enable nginx(设为开机自启,非必需但推荐) -
sudo systemctl start nginx(首次启动)
此后所有 systemctl stop nginx 都会走 ExecStop,触发真正的优雅退出。
验证是否真正优雅停机
别只看命令返回成功,要观察行为:
- 执行
sudo systemctl stop nginx后,立刻运行ss -tnlp | grep :80—— 监听端口应迅速消失 - 同时运行
watch -n 0.5 'ps aux | grep nginx'—— worker 进程数应逐个归零,而非瞬间全灭 - 若后端有长连接(如 SSE 或 keepalive 10s),该连接应完成响应后再断开,不会被中断
如果 stop 卡住或超时,检查 journalctl -u nginx -n 30,常见原因包括:proxy_read_timeout 过长、worker 进程卡死、SSL handshake 未完成等。


















