Nginx upstream自动剔除与恢复需max_fails、fail_timeout和proxy_next_upstream协同配置:失败在时间窗口内达阈值则临时隔离,超时后首次请求试探恢复;须启用proxy_next_upstream捕获5xx等错误,配合主动健康检查提升可靠性。

要让 Nginx 的 upstream 真正实现后端节点的自动剔除与恢复,不能只写 max_fails,必须和 fail_timeout、proxy_next_upstream 一起协同配置。它不是“失败几次就永久下线”,而是在指定时间窗口内连续失败达到阈值后临时隔离,并在超时后主动试探恢复。
max_fails 和 fail_timeout 要成对设置
这两个参数必须一起调,单独改一个容易失衡:
- 常规 Web 服务(如用户查询、管理后台):设为
max_fails=3 fail_timeout=30s。30 秒内连续失败 3 次才摘除,能过滤偶发超时或 GC 暂停抖动,又不会让故障节点长期拖累流量 - 高 QPS 场景(如 API 网关、订单中心):用
max_fails=15 fail_timeout=10s。缩短检测窗口,提高失败容错数,避免瞬时毛刺反复触发摘除 - 慢响应服务(如报表导出、大文件上传):设为
max_fails=2 fail_timeout=60s。防止一次耗时 45 秒的正常请求被误判为 timeout 并计入失败计数 - 强一致低频接口(如支付回调、风控通知):可设
max_fails=1 fail_timeout=10s。首次失败即隔离,降低关键链路风险
必须启用 proxy_next_upstream 才会真正计数失败
Nginx 默认只把连接拒绝(connect refused)和连接超时(timeout)算作失败,HTTP 错误码(如 502/503)默认不触发 max_fails 累加。不配这个,后端返回一堆 502,节点也不会被摘。
在 location 块中加上:
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
再配合控制重试行为:
-
proxy_next_upstream_tries 3;—— 最多换 2 台其他节点重试 -
proxy_next_upstream_timeout 10s;—— 整个重试过程总耗时不超 10 秒,避免用户卡顿
节点恢复不是定时心跳,而是“首次请求试探”
被标记为 down 的节点,在 fail_timeout 时间结束后并不会自动轮询探测。Nginx 是等下一个新请求到达时,才向该节点发一次试探请求:
- 试探成功 → 立即重新加入 upstream 轮询池
- 试探失败 → 继续标记为 down,再等下一个请求来重试
- 如果所有主节点都 down 了,Nginx 会强制重试全部节点(包括刚被标记 down 的),此时若某台已恢复,就能立刻承接流量
建议叠加主动健康检查提升可靠性
被动检查依赖真实请求,低流量时段可能几十秒都不触发恢复。生产环境建议补上主动健康检查:
- 商业版 Nginx Plus 支持
health_check指令,可配置间隔、超时、期望状态码 - 开源版可通过第三方模块(如 nginx_upstream_check_module)或外部探活脚本 + API 动态更新 upstream 实现类似效果
- 即使使用主动检查,仍建议保留
max_fails配置作为兜底,防止探活本身失效时失去保护











