Nginx如何实现后端重启时的连接优雅迁移过程详解?
- 内容介绍
- 文章标签
- 相关推荐
本文共计749个文字,预计阅读时间需要3分钟。
当 `
连接不中断:靠的是 Worker 进程的优雅退出机制
Nginx 的 master 进程不处理请求,只管理 worker 进程。当执行 nginx -s reload 或后端发生变更时:
- master 进程先校验新配置语法是否正确;若失败,旧配置继续运行,业务零感知
- 校验通过后,master 启动一批使用新配置的新 worker 进程
- 同时向旧 worker 进程发送 QUIT 信号,而非 KILL 或 TERM
- 旧 worker 收到 QUIT 后立即停止 accept 新连接,但会持续处理已建立的 TCP 连接(包括正在传输的 HTTP 请求、长连接、WebSocket 等),直到所有请求完成才退出
后端切换时流量不丢:依赖 upstream 健康探测与失败策略
如果只是后端应用重启(如 Java 服务停机再启动),Nginx 需要识别其临时不可用,并把新请求绕过它:
- 在 upstream 块中启用健康检查(需编译含
nginx-plus或第三方nginx-upstream-check-module) - 或使用原生参数:
max_fails=3 fail_timeout=30s,表示连续 3 次超时/502/504 后,将该 server 标记为不可用,30 秒内不再转发请求 - 搭配
proxy_next_upstream error timeout http_502 http_504,让失败请求自动重试下一个后端(注意:仅限幂等请求,如 GET/HEAD) - 重启期间,Nginx 自动把新请求分发给其余健康的后端,用户无感
确保旧连接彻底释放:可观察 + 可控的收尾手段
reload 后旧 worker 进程不会立刻消失,需确认它们是否已空闲退出:
- 查看 worker 进程数变化:
ps aux | grep 'nginx: worker',对比 reload 前后数量 - 检查指定端口连接状态:
netstat -anp | grep :8080 | grep ESTABLISHED(替换为你的后端端口) - 如需加速清理,可在 nginx.conf 中设置:
worker_shutdown_timeout 10s,强制旧 worker 在 10 秒内终止未完成请求(慎用,可能中断长任务)
进阶保障:配合后端就绪探针实现真正平滑上线
光靠 Nginx 被动探测不够可靠。更稳妥的做法是让后端主动通知 Nginx:“我准备好了”:
- 后端启动后,先不注册到负载均衡,而是提供一个
/health/ready接口返回 200 - Nginx 使用
check模块定期探测该路径,仅当探测成功才将其纳入 upstream 流量池 - 或结合 Consul、Nacos 等服务发现组件,由注册中心触发 Nginx 配置热更新(如 via OpenResty + Lua)
本文共计749个文字,预计阅读时间需要3分钟。
当 `
连接不中断:靠的是 Worker 进程的优雅退出机制
Nginx 的 master 进程不处理请求,只管理 worker 进程。当执行 nginx -s reload 或后端发生变更时:
- master 进程先校验新配置语法是否正确;若失败,旧配置继续运行,业务零感知
- 校验通过后,master 启动一批使用新配置的新 worker 进程
- 同时向旧 worker 进程发送 QUIT 信号,而非 KILL 或 TERM
- 旧 worker 收到 QUIT 后立即停止 accept 新连接,但会持续处理已建立的 TCP 连接(包括正在传输的 HTTP 请求、长连接、WebSocket 等),直到所有请求完成才退出
后端切换时流量不丢:依赖 upstream 健康探测与失败策略
如果只是后端应用重启(如 Java 服务停机再启动),Nginx 需要识别其临时不可用,并把新请求绕过它:
- 在 upstream 块中启用健康检查(需编译含
nginx-plus或第三方nginx-upstream-check-module) - 或使用原生参数:
max_fails=3 fail_timeout=30s,表示连续 3 次超时/502/504 后,将该 server 标记为不可用,30 秒内不再转发请求 - 搭配
proxy_next_upstream error timeout http_502 http_504,让失败请求自动重试下一个后端(注意:仅限幂等请求,如 GET/HEAD) - 重启期间,Nginx 自动把新请求分发给其余健康的后端,用户无感
确保旧连接彻底释放:可观察 + 可控的收尾手段
reload 后旧 worker 进程不会立刻消失,需确认它们是否已空闲退出:
- 查看 worker 进程数变化:
ps aux | grep 'nginx: worker',对比 reload 前后数量 - 检查指定端口连接状态:
netstat -anp | grep :8080 | grep ESTABLISHED(替换为你的后端端口) - 如需加速清理,可在 nginx.conf 中设置:
worker_shutdown_timeout 10s,强制旧 worker 在 10 秒内终止未完成请求(慎用,可能中断长任务)
进阶保障:配合后端就绪探针实现真正平滑上线
光靠 Nginx 被动探测不够可靠。更稳妥的做法是让后端主动通知 Nginx:“我准备好了”:
- 后端启动后,先不注册到负载均衡,而是提供一个
/health/ready接口返回 200 - Nginx 使用
check模块定期探测该路径,仅当探测成功才将其纳入 upstream 流量池 - 或结合 Consul、Nacos 等服务发现组件,由注册中心触发 Nginx 配置热更新(如 via OpenResty + Lua)

