加权轮询(weight)是老旧服务器优雅下线最轻量可控的方式:先降权观察稳定性,再分阶段归零,配合健康检查与连接draining,确保不中断、不报错。

老旧服务器下线不是直接踢掉,而是让它逐步退场——加权轮询(weight)是实现这个过渡最轻量、最可控的方式。核心思路是:先大幅降低其权重,观察稳定性;再逐步归零,配合健康检查与连接 draining,让流量自然滑出,不中断、不报错。
用 weight 逐步调低,避免流量突降
老旧服务器性能下降后,若直接设 weight=0,所有新请求瞬间切走,看似“快”,实则掩盖了潜在问题(如长连接堆积、下游依赖未就绪)。更稳妥的做法是分阶段调整:
- 第一阶段:将 weight 从默认 1 降至 2–3(例如新机 weight=10,旧机先调为
weight=4),承接约 25%–30% 流量,验证 CPU、GC、响应延迟是否可控 - 第二阶段:确认稳定后,再降至
weight=1或weight=0.5,进一步收窄流量入口 - 第三阶段:最后设为
weight=0,Nginx 不再主动派发新请求,仅维持已有连接
每次调整后执行 nginx -s reload(或通过 dyups/Lua 动态更新),无需重启,不影响其他节点。
搭配 max_fails + health_check 主动识别不可用
仅靠 weight 不能应对突发故障。必须让 Nginx 主动“感知”旧机是否真的扛得住:
- 在 upstream 中启用主动健康检查(需编译
nginx-module-healthcheck或使用 OpenResty):check interval=5 rise=2 fall=3 timeout=3 type=http;check_http_send "GET /health/ready HTTP/1.1\r\nHost: api.example.com\r\n\r\n";check_http_expect_alive http_2xx http_503; - 把
/health/ready接口逻辑改写:当旧机进入下线流程时,主动返回503 Service Unavailable,Nginx 会在 3 次失败后立即标记为 down,加速摘流 - 补上容错参数:
server 192.168.1.50:8080 weight=0.5 max_fails=1 fail_timeout=10s;,避免单次超时误判,又保证快速响应异常
控制连接 draining 时间窗,等旧机自己“清完场”
weight=0 后,Nginx 不再转发新请求,但已建立的连接仍会持续处理。这时关键不是 Nginx 做什么,而是给旧机留足退出时间:
- 后端应用收到 SIGTERM 后,立即关闭新连接入口(如 Spring Boot 的
server.tomcat.connection-timeout=-1+/actuator/health返回 DOWN),但不强制 close 现有 socket - Nginx 层设置
proxy_read_timeout 90s;(建议 ≥ 业务最长链路耗时),确保后端有足够时间完成正在处理的请求 - 开启
proxy_ignore_client_abort on;,防止用户关页面导致 Nginx 中断后端还在跑的请求 - 通过
stub_status或nginx-module-vts监控Active connections和 upstream 的Active数,确认归零后再终止旧机进程
上线前必须验证闭环效果
配置写得再全,不验证等于没做。重点看三件事是否连通:
- 调用
curl http://nginx-ip/status,确认目标旧机状态已变为down或unhealthy,且 active conn 缓慢下降 - 抓包或查 Nginx access log,确认新请求不再打到该 IP,而历史长连接仍在正常响应
- 模拟下线全流程:改 health 接口 → reload → 查 status → 等 active conn 归零 → kill 进程,全程无 502/504 报错
不复杂但容易忽略的是:weight 调整只是“指挥棒”,真正决定是否优雅的,是后端能否稳住 draining 窗口、Nginx 能否正确识别并尊重这个节奏。











