proxy_next_upstream 仅在nginx已建立tcp连接但后端响应异常(如超时、502、连接中断)时触发重试,不处理连接拒绝、dns失败等前置问题;需配合tries、timeout及tomcat线程池、超时等配置协同生效。

用 proxy_next_upstream 解决 Tomcat 偶发 502,核心不是“加配置就完事”,而是要理解它在什么条件下触发重试、哪些错误可重试、以及后端不配合时它根本无效。
明确 proxy_next_upstream 的触发边界
该指令只在 Nginx 已与后端建立 TCP 连接、但收到异常响应(或超时)时才尝试换节点。它不解决连接拒绝(Connection refused)、DNS失败、SSL握手失败等前置问题。
常见有效触发场景包括:
安全更新和维护 CLI Proxy API(CPA)部署与配置。用于 CPA 镜像升级、配置变更、认证目录兼容修复、上线验证与回滚。适用于用户提到“CPA 更新/升级/配置改了/容器重建/回滚”等场景。
- Tomcat 进程卡住、线程耗尽,无法及时返回 HTTP 响应(Nginx 等待超时)
- Tomcat 主动关闭连接(如 OOM 后强制 kill socket)
- 返回了 502/503/504 状态码(需显式配置
http_502等) - 响应体不完整(
off默认不重试,需加non_idempotent或确保方法幂等)
必须搭配的关键配置项
单独写 proxy_next_upstream error timeout http_502; 很可能没效果。还需同步设置:
-
proxy_next_upstream_tries 3;—— 最多重试次数(含首次),建议 2–3 -
proxy_next_upstream_timeout 10s;—— 所有重试总耗时上限,避免拖慢整体响应 -
proxy_connect_timeout 3s;+proxy_send_timeout 15s;+proxy_read_timeout 15s;—— 单次请求各阶段超时,要明显小于proxy_next_upstream_timeout -
proxy_buffering off;(可选)—— 若 Tomcat 返回流式响应且易中断,关缓冲有助于更早发现截断
Tomcat 侧必须做好的配合动作
Nginx 重试的前提是:后端故障是瞬时、局部、可恢复的。如果 Tomcat 自身未做基础防护,Nginx 重试只是掩盖问题:
- 确认
maxThreads设置合理(如 200–400),避免线程池打满后所有请求都超时 - 启用
connectionTimeout="20000"和keepAliveTimeout="15000",防止连接堆积 - 检查是否有慢 SQL、未关闭的流、死循环等导致单请求长时间阻塞
- 若使用 Spring Boot,确认
server.tomcat.max-connections和max-threads匹配 Nginx 并发预期
验证是否真正生效的方法
别只看日志有没有 “upstream:” 字样。真实验证步骤:
- 在 Tomcat 的某台实例上临时模拟瞬时故障:
kill -STOP $PID(暂停进程),再发请求,观察 Nginx 是否在proxy_read_timeout后自动切到健康节点并返回 200 - 抓包确认:Nginx 发出第一个请求后无响应,等待约
proxy_read_timeout,再向另一台 upstream 发起新请求(非复用原连接) - 查看 Nginx
error.log中类似upstream timed out (110: Connection timed out) while reading response header from upstream,且后续行出现reusing connection to ...或切换 IP 记录










