302重定向在nginx中不替代upstream负载均衡,而是协同实现客户端侧临时调度:302负责策略性跳转决策,upstream负责服务端透明分发,二者分层协作、各司其职。

在 Nginx 中,302 重定向本身不是负载均衡机制,但它可以和 upstream 负载均衡器协同工作,实现有状态、可感知、按需触发的临时流量调度与分流。关键在于:用 302 主动“引导客户端跳转”,而非 proxy_pass 被动转发;让客户端自己去访问目标服务,从而绕过 Nginx 的后端连接池,同时保留控制权和灵活性。
明确分工:302 负责“决策与告知”,upstream 负责“稳定承载”
不要把 302 和 upstream 混在同一路径做“跳转+代理”。正确逻辑是:
- 302 用于临时、条件性、客户端侧生效的调度(如灰度用户跳新域名、活动页导流、维护中提示)
- upstream 用于长期、无感、服务端侧透明的负载分发(如 API 请求打到多个后端实例)
- 二者可共存于同一配置中,但作用层级不同:302 在 server 或 location 入口层做判断并终止流程;upstream 在需要 proxy_pass 的路径中承接真实请求
典型配合场景与配置方式
场景一:对部分用户临时跳转至新集群(灰度发布)
不改 DNS,也不动 upstream,而是让指定用户直接访问新域名下的服务集群(该新域名背后也配了 upstream):
- 用
if或map提前识别灰度标识(如 Cookie、Header、参数) - 匹配成功则
return 302 https://beta.example.com$request_uri; -
beta.example.com的 server 块中独立配置 upstream,负责将请求分发到 beta 集群的多台机器
场景二:主站临时维护,所有非静态资源跳转至备用站点
避免全站 proxy_pass 增加 Nginx 压力,改用 302 引导客户端直连备用站(其自身也带负载能力):
- 排除图片/CSS/JS 等静态资源(防止跳转拖慢页面),其余请求统一 302 到
https://backup.example.com$request_uri -
backup.example.com的 upstream 可配置多台容灾服务器,支持健康检查与自动剔除
场景三:按地理位置或设备类型,跳转至不同区域的负载均衡入口
比如移动端用户跳 m.example.com,海外用户跳 global.example.com,每个子域都自有 upstream 分组:
- 利用
$http_user_agent或$geoip_country_code(需加载 geoip 模块)做判断 - 分别 return 302 到对应子域名,由各子域的 upstream 完成后续负载分发
为什么不用 rewrite + proxy_pass 替代?
看似都能“把流量送走”,但语义和效果完全不同:
-
proxy_pass http://backend;是服务端转发,客户端无感知,URL 不变,SEO 和调试都不直观 -
return 302 https://new-site.com$request_uri;是明确告知客户端“请你自己去新地址”,URL 变更可见,便于监控、AB 测试归因、用户反馈定位 - 当目标服务本身也需横向扩展时,302 后的域名天然可配独立 upstream,形成两级调度:第一级(Nginx 入口)做策略分流,第二级(目标域名)做容量负载
上线前必须验证的三个重点
配置 reload 后,不能只看页面是否跳转,要确认底层行为符合预期:
- 用
curl -I http://example.com/path?test=1检查响应头:必须含HTTP/1.1 302 Found和正确的Location,且$request_uri完整保留参数 - 打开浏览器开发者工具 → Network 标签,确认跳转链干净(只有一次 302),没有嵌套跳转或意外降级为 301
- 在无痕窗口多次访问,排除浏览器缓存干扰;若 CDN 层加了缓存头,需同步清理或禁用 Cache-Control











