排查Nginx轮询下重定向死循环,需确认重定向是否被错误复用、跨节点失效及Location与原始请求不匹配;核心是后端硬编码跳转URL、X-Forwarded头未透传、proxy_redirect未配置导致闭环。

排查 Nginx 轮询负载均衡下因后端返回重定向引发的死循环,核心是确认重定向是否被错误复用、是否跨节点失效、以及 Location 值是否与客户端原始请求不匹配。重点不在轮询本身,而在重定向响应如何被不同后端节点重复生成并无法收敛。
看响应链:用 curl -v 抓真实跳转路径
在客户端或跳转发起侧执行:
- curl -v https://yourdomain.com/login,观察每一步的 Location: 响应头和 HTTP/1.1 302 状态码
- 若连续出现多个
Location: https://yourdomain.com/login(目标不变),基本确认死循环 - 添加
-H "X-Request-ID: test123"并在 Nginx access_log 中启用$request_id,可关联同一请求在多个 upstream 节点的日志行 - 检查响应头中是否带
X-Upstream: node1或类似自定义标识,确认是否真的轮到了不同后端
查 Location 来源:盯住后端是否硬编码跳转地址
死循环往往源于后端服务返回了固定域名的绝对跳转 URL,例如:
-
Location: http://example.com/dashboard(写死 HTTP) -
Location: https://backend.internal/api/login(暴露内网地址) -
Location: //example.com/next(协议相对,但前端未正确解析)
这类响应经 Nginx 转发后,浏览器按绝对地址重发请求,Nginx 又轮询到另一个后端节点,该节点照例返回同样 Location,形成闭环。必须让后端基于 X-Forwarded-Proto 和 X-Forwarded-Host 动态构造跳转地址。
验 Nginx 透传与重写:确认关键头是否生效、proxy_redirect 是否匹配
在 proxy_pass 所在 location 块中,必须有:
- proxy_set_header X-Forwarded-Proto $scheme;(告诉后端原始是 HTTP 还是 HTTPS)
- proxy_set_header X-Forwarded-Host $host;(避免后端拼错 Host)
- proxy_redirect ~^http://[^/]+(/.*)$ $1;(剥离后端返回的绝对 Location 域名,只留路径)
- 临时加
add_header X-Debug-Location "$upstream_http_location" always;,把后端原始 Location 透出到响应头,便于比对
查会话与 Cookie:排除因登录态不一致导致的反复跳转
例如未登录用户访问 /admin → 后端 A 返回 302 到 /login → 用户带 Cookie 访问 /login → Nginx 轮询到后端 B → B 检查 Session 不存在 → 再次 302 到 /login:
- 检查 Set-Cookie 是否含
Domain=yourdomain.com且未设Secure时混用 HTTP/HTTPS - 确认所有后端节点共享同一套 Session 存储(如 Redis),而非本地内存
- 临时启用
ip_hash;在 upstream 中做会话保持,验证是否关闭轮询后循环消失——若消失,说明是 Session 不一致问题
不复杂但容易忽略:死循环极少是 Nginx 自己“主动跳转”造成的,几乎全是后端重定向逻辑 + 头信息透传缺失 + 负载分发机制共同作用的结果。先抓包看 Location 值,再查它从哪来、是否被重写、是否被正确消费,三步到位。


















