要让后端节点故障时客户端几乎感觉不到中断,关键是在失败后由proxy_next_upstream快速、可控地切换健康节点;默认仅对error和timeout重试,生产中建议显式添加http_502/503/504,禁用http_404/403,慎用http_500;需配对设置tries(如3)与timeout(如10s);必须配置max_fails与fail_timeout实现被动健康检查,或启用主动健康检查;重试前提为请求幂等,get/head可安全重试,post/put/delete需业务层严格保障幂等性。

要让后端节点故障时客户端几乎感觉不到中断,关键不是“加一个指令”,而是让 proxy_next_upstream 在正确时机、以可控方式换节点——它不预测故障,只在失败后快速兜底。
明确哪些错误值得重试
默认只对连接失败(error)和超时(timeout)重试。生产中建议显式补充:
-
http_502/http_503/http_504:网关类错误,大概率是后端瞬时不可用,换节点重试往往成功 - 不加
http_404或http_403:这类是业务逻辑结果,重试不会改变响应,反而可能重复扣费或提交 - 慎加
http_500:除非确认是偶发异常(如 GC 暂停),否则应先排查日志,而非靠重试掩盖问题
限制重试次数与总耗时
这两个参数必须成对设置,否则容易引发雪崩或长尾延迟:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
-
proxy_next_upstream_tries 3:最多尝试 3 个不同节点(含首次),不是“重试 3 次” -
proxy_next_upstream_timeout 10s:从第一次请求发出开始计时,10 秒内无论试了几个节点,超时即返回错误 - 搭配建议:若单次 P95 响应在 3–4 秒,设为
tries 3+timeout 10s,既能覆盖一次有效重试,又防拖累整体
让重试真正落在健康节点上
没有健康检查的重试,等于反复打坏节点:
- 在
upstream中每个server后加max_fails=3 fail_timeout=30s:连续 3 次失败(包括重试触发的 502/504)后,该节点 30 秒内不再参与调度 - 可选加
backup节点:仅当所有主节点被标记为不可用时才启用,作为最后一道防线 - 更可靠的方式是启用主动健康检查(Nginx Plus 或 OpenResty +
upstream_check_module):health_check interval=3 fails=2 passes=2
守住幂等底线,避免重复执行
重试本质是重复发请求,安全的前提是“重复无副作用”:
-
GET/HEAD请求天然幂等,可放心开启 502/504 重试 -
POST/PUT/DELETE默认不重试,Nginx 有内置保护机制 - 若业务层已严格保障幂等(例如通过
X-Request-ID+ Redis 记录处理状态),且日志可追溯,才考虑谨慎开启;否则宁可让客户端自行处理
不复杂但容易忽略










