proxy_pass本身不实现故障转移,真正的故障转移依赖upstream块配置(max_fails/fail_timeout/backup)与proxy_next_upstream指令协同:前者标记不可用节点并启用备用节点,后者在error、timeout、500/502/503/504等特定错误时触发请求级重试,配合tries和timeout限制重试行为。

proxy_pass 本身不直接实现故障转移,它只是请求转发指令;真正的故障转移能力来自 upstream 块的配置 + proxy_next_upstream 等配套指令协同工作。关键不是 proxy_pass 写成什么样,而是它指向的 upstream 是否具备容错能力、以及 Nginx 是否被明确告知“什么情况下该换节点重试”。
用 upstream 定义带容错的后端组
proxy_pass 必须指向一个 upstream 块(如 proxy_pass http://backend;),而故障转移逻辑全在 upstream 内部定义:
- max_fails=3 fail_timeout=30s:某节点连续 3 次请求失败(连接失败、超时、5xx 响应等),就被标记为不可用,30 秒内不再分发请求
- backup:该 server 行末尾加 backup,表示仅当所有非 backup 节点都不可用时才启用
- weight=1(可选):显式设权重,便于后续调整流量比例
示例:
upstream backend {server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 backup;
}
靠 proxy_next_upstream 触发请求级重试
即使 upstream 里节点状态已更新,单次请求仍可能失败。这时需要 proxy_next_upstream 显式告诉 Nginx:“遇到哪些情况就立刻换一台服务器再试一次”:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- error:连接后端失败(如拒绝连接、DNS 解析失败)
- timeout:连接或响应超时
- http_500 http_502 http_503 http_504:收到这些网关类错误响应时也重试
- proxy_next_upstream_tries 3:最多尝试 3 台不同后端(含首次)
- proxy_next_upstream_timeout 10s:整个重试过程总耗时不超过 10 秒
这部分必须写在 location 块中,与 proxy_pass 同级:
location /api/ {proxy_pass http://backend;
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
proxy_next_upstream_tries 3;
proxy_next_upstream_timeout 10s;
}
补充主动健康检查(推荐生产环境启用)
被动容错(靠失败请求触发)有滞后性。更稳妥的方式是加主动探测,让 Nginx 定期发健康检查请求,提前发现宕机节点:
- 开源版需编译安装 nginx_upstream_check_module
- 在 upstream 块中添加 check 指令:check interval=3 rise=2 fall=5 timeout=1 type=http
- 配合 check_http_send "HEAD /health HTTP/1.0\r\n\r\n" 和 check_http_expect_alive http_2xx,确保只认 2xx 为健康
这样节点还没开始收真实流量,Nginx 就已通过 /health 接口确认其可用性。
别漏掉基础代理头和路径处理
故障转移生效的前提是请求能正确抵达后端并被识别。以下两点直接影响可用性:
- 路径拼接要一致:location /api/ 对应 proxy_pass http://backend/(结尾带斜杠),否则后端收到的是 /api/users 而非 /users,容易 404
- 四个关键头必须设置:Host、X-Real-IP、X-Forwarded-For、X-Forwarded-Proto——缺一可能导致后端鉴权失败、跳转异常或日志 IP 错误

















