nginx master进程通过unix信号而非信号量控制服务关闭流程;sigterm/sigquit触发优雅关闭,master通知worker停止接受新连接并处理完现存请求后退出。

在 Nginx 中,Master 进程并不使用信号量(semaphore)来控制服务关闭流程,而是通过标准的 Unix 信号(signal)机制实现进程间通信与生命周期管理。这是一个常见误解——“信号量”是用于线程/进程同步的内核对象(如 POSIX semaphores 或 System V semaphores),而 Nginx 的优雅停止、重载、平滑升级等操作,全部依赖的是 发送特定信号给 Master 进程,由其协调 Worker 进程行为。
Master 进程响应的核心信号
Nginx Master 进程监听并处理以下关键信号:
- SIGTERM:触发快速关闭——Master 立即向所有 Worker 发送 SIGQUIT,Worker 停止接受新连接,处理完当前请求后退出;随后 Master 自身退出。
- SIGQUIT:触发优雅关闭——行为与 SIGTERM 相同(Nginx 官方文档明确说明两者在关闭语义上一致)。
- SIGUSR2:启动新 Master + Worker(用于平滑升级二进制文件)。
- SIGUSR1:重新打开日志文件(常用于日志轮转)。
- SIGHUP:重载配置——Master 检查配置语法,成功则 fork 新 Worker,逐步用新 Worker 替换旧 Worker(旧 Worker 处理完现存请求后退出)。
为什么不是信号量?
信号量需显式创建、初始化、等待和释放,适用于需要互斥访问共享资源的并发场景(如多线程计数器)。而 Nginx 的关闭流程本质是异步事件驱动的指令下发:
- 用户执行
nginx -s quit或kill -s QUIT $(cat nginx.pid),本质是向 Master 发送 SIGQUIT; - Master 收到信号后,通过
kill()系统调用向各 Worker 进程发送 SIGQUIT; - Worker 接收到后进入“优雅退出”状态机,不再 accept 新连接,但继续处理已建立的连接和请求;
- 无共享内存或临界区需要加锁保护,无需信号量介入。
实际关闭流程的关键细节
以 nginx -s quit(发送 SIGQUIT)为例:
- Master 不会立即终止,而是先通知所有 Worker 进入退出流程;
- Worker 进程设置内部标志位,拒绝新连接(
ngx_close_listening_sockets()),但保持已有连接活跃; - 当所有 Worker 正常退出后,Master 才清理资源、删除 pid 文件并退出;
- 若 Worker 卡死或超时未退出(默认无硬性超时,但可通过
worker_shutdown_timeout配置),Master 可能残留,需人工干预(如 SIGKILL)。
验证与调试建议
可通过以下方式确认信号行为:
- 用
strace -p $(cat /var/run/nginx.pid) -e trace=signal跟踪 Master 接收的信号; - 查看 Worker 进程状态:
ps aux | grep nginx,关闭过程中应看到 Worker 数量逐渐减少; - 检查 error.log,优雅关闭时通常记录
"exiting"或"gracefully shutting down"日志。










