2026-06-02 20:37:36
Nginx实现平滑重启的核心机制是通过信号触发进程替换,避免服务中断。具体实现方式如下:
发送USR2信号启动新进程
执行命令:kill -USR2 $(cat /var/run/nginx.pid)
作用:通知旧master进程启动新二进制文件,新进程继承旧进程的监听套接字(文件描述符)。
关键操作:
旧master将nginx.pid重命名为nginx.pid.oldbin,新master使用原文件名创建PID文件。
新master通过环境变量NGINX传递旧进程的监听套接字FD(文件描述符),直接复用端口而非重新绑定。
发送QUIT信号关闭旧进程
执行命令:kill -QUIT $(cat /var/run/nginx.pid.oldbin)
作用:优雅终止旧master及其worker进程,新进程完全接管服务。
关键点:旧进程会等待所有活跃请求处理完毕后再退出,确保无业务中断。
底层技术原理
文件描述符继承:新master通过fork()+execve()启动时,继承旧进程的监听套接字FD,避免端口冲突。
环境变量传递:Nginx将FD列表编码到环境变量中,新进程解析后直接使用这些FD,无需重新bind()/listen()。
日志验证:通过日志可观察到inherited sockets记录,证明FD复用成功。
与手动启动的区别
手动启动新实例会因端口冲突失败(如80端口被占用),而信号触发的方式通过进程间FD传递规避了此问题。
Nginx源码中的ngx_exec_new_binary()和ngx_add_inherited_sockets()函数实现了FD传递和监听套接字复用。
总结:Nginx平滑重启通过信号驱动进程替换,利用操作系统FD继承机制实现端口复用,结合优雅退出策略确保服务连续性。此方法无需额外配置,是Nginx高可用的核心设计之一。