nginx 的 upstream 模块在节点宕机后,默认行为是将其标记为不可用并剔除出轮询列表,当后端健康检查通过或达到重试间隔时,nginx 会自动将该节点重新加入可用池。要实现这一自动恢复机制,核心在于配置 max_fails 和 fail_timeout 参数,前者定义失败次数阈值,后者定义重置计数的时间窗口。只要后端服务重启并正常响应 http 请求,nginx 就会在下一个 fail_timeout 周期内尝试将流量重新分发到该节点。

如何配置 Nginx 实现故障转移与自动恢复
要启用自动恢复功能,需要在 upstream 块中为每个 server 指定 max_fails 和 fail_timeout。例如,设置 max_fails=3 表示如果连续 3 次连接失败(如超时或拒绝连接),Nginx 会将该节点标记为宕机;设置 fail_timeout=10s 表示在 10 秒内累计失败超过 3 次才触发标记,且标记后的 10 秒内不再向该节点发送请求。在这 10 秒结束后,Nginx 会尝试向该节点发送一个探测请求,如果成功,则立即恢复其负载均衡状态。

worker_processes 1;
events {
worker_connections 1024;
}
http {
upstream backend_pool {
# 定义加权轮询策略
# max_fails: 失败次数阈值,默认为 1
# fail_timeout: 失败统计的时间窗口及节点不可用的持续时间,默认为 10s
server 192.168.1.10:8080 weight=5 max_fails=3 fail_timeout=10s;
server 192.168.1.11:8080 weight=3 max_fails=3 fail_timeout=10s;
server 192.168.1.12:8080 weight=2 max_fails=3 fail_timeout=10s;
}
server {
listen 80;
location / {
proxy_pass http://backend_pool;
# 可选:设置代理超时时间,确保快速检测故障
proxy_connect_timeout 5s;
proxy_read_timeout 5s;
}
}
}
上述配置中,192.168.1.10 权重最高,但若其在 10 秒内连续失败 3 次,将被暂时移除。其他两个节点继续承担流量。一旦 192.168.1.10 恢复,Nginx 会在下一个 10 秒周期开始时尝试重连,成功后即恢复其权重参与轮询。
如何验证节点恢复后的流量分配是否生效
验证节点恢复的关键是观察 Nginx 的错误日志和实际请求转发情况。当节点被标记为宕机时,Nginx 会在 error.log 中记录类似 upstream temporarily disabled 的信息。恢复后,该日志停止出现,且后续请求开始均匀分布到新恢复的节点上。可以通过模拟节点宕机、等待 fail_timeout 时间、然后启动节点,最后使用 curl 多次访问来验证流量是否重新流入。

# 模拟客户端请求脚本 (bash)
for i in {1..20}; do
curl -s -o /dev/null -w "%{http_code}\n" http://localhost/
done
# 查看 Nginx 错误日志确认状态变化
tail -f /var/log/nginx/error.log | grep "upstream"
在实际操作中,建议配合监控工具(如 Prometheus + Grafana)观察上游服务器的活跃连接数和错误率,以直观判断恢复时机。若发现节点频繁在“可用”和“不可用”之间切换,可能是由于网络抖动导致误判,此时可适当增大 fail_timeout 或调整 proxy_next_upstream 策略,避免不必要的流量震荡。
当节点恢复但返回 502 错误时如何处理
如果节点在 fail_timeout 结束后被重新加入轮询,但首次请求仍返回 502 Bad Gateway,说明该节点虽然端口可达,但应用层尚未完全就绪。此时 Nginx 会根据 proxy_next_upstream 指令决定是否重试其他节点。默认情况下,proxy_next_upstream 包含 error 和 timeout,因此遇到 502 时会尝试下一个可用节点,而不会立即将刚恢复的节点再次标记为宕机(除非连续失败次数达到 max_fails)。为确保平滑恢复,应在应用启动完成后暴露健康检查接口,并在 Nginx 中配置基于 HTTP 的健康检查(需第三方模块如 nginx-upstream-check-module),而非仅依赖 TCP 连接成功率。


















