Nginx轮询摘流不断连的关键在于weight=0即时停派新请求、proxy_read_timeout保障存量连接处理时间、后端主动停入口并等连接归零三者协同,而非轮询算法自身具备状态感知能力。

要让 Nginx 轮询算法在摘除某个后端节点时不中断正在处理的连接,关键不是轮询本身“变聪明”,而是通过配置组合实现:立即停止派发新请求 + 允许存量连接自然完成 + 后端主动配合退出节奏。
配置 weight=0 实现即时摘流
这是最直接、最可控的方式,无需等待探测或失败:
- 将目标节点设为
weight=0,例如:upstream backend { server 192.168.1.10:8080 weight=0; server 192.168.1.11:8080; server 192.168.1.12:8080; } - 修改后执行
nginx -s reload(或用 dyups/Lua 模块热更新),Nginx 立即停止向该节点分发新请求。 - 已建立的长连接(如 HTTP/1.1 keepalive、WebSocket)仍可继续收发数据,不会被强制断开。
启用健康检查加速状态同步
仅靠 weight=0 是手动操作,配合健康检查可自动响应后端退出意图:
- 在 upstream 中启用探活(需编译
nginx_upstream_check_module):upstream backend { check interval=3 rise=2 fall=3 timeout=1 type=http; check_http_send "GET /health HTTP/1.0\r\n\r\n"; check_http_expect_alive http_2xx http_3xx; server 192.168.1.10:8080 weight=0; server 192.168.1.11:8080; server 192.168.1.12:8080; } - 后端下线前,将
/health接口返回503 Service Unavailable,触发 Nginx 连续探测失败后自动标记为不可用,进一步确保流量不回切。
调整代理参数保障 draining 时间窗
Nginx 必须给后端留出处理存量请求的时间,避免超时中断:
- 设置足够长的
proxy_read_timeout(建议 ≥ 业务最长响应时间,如 60–90 秒):location /api/ { proxy_pass http://backend; proxy_read_timeout 90; proxy_ignore_client_abort on; # 用户关页面,不中断后端任务 proxy_http_version 1.1; proxy_set_header Connection "keep-alive"; } -
proxy_ignore_client_abort on很关键:防止用户关闭浏览器导致 Nginx 主动终止后端仍在运行的请求。
后端必须主动配合完成闭环
Nginx 是被动协调者,真正零丢失依赖后端行为:
- 下线前先关闭新请求入口:Spring Boot 调
/actuator/health切 DOWN;Tomcat 停 connector;Netty shutdown EventLoopGroup。 - 保持已有连接可读写,等待活跃连接自然关闭(可通过
stub_status监控Active connections是否归零)。 - 确认连接数清零后再终止进程;若使用 systemd,建议配置
TimeoutStopSec=120留足缓冲。
不复杂但容易忽略的是:weight=0 + proxy_read_timeout + 后端停入口,三者缺一不可。轮询算法本身不感知状态,真正的优雅来自这套协同机制。


















