Nginx中动态后端分流需用map指令在http块顶层将请求特征映射为预定义upstream名称,proxy_pass引用该变量(如http://$upstream_name),不可带路径,且upstream名称必须严格匹配已声明的upstream块。

在 Nginx 负载均衡中,变量本身不能直接用于 upstream 块内动态解析 IP 或域名(比如 server $backend_host; 是非法的),但可以通过 map + upstream 名称 + proxy_pass 这一组合,实现运行时按请求特征选择后端集群的效果——这才是生产环境真正可行、原生支持、无需额外模块的方案。
核心思路:把“路由决策”提前到 map 阶段
map 指令在 Nginx 启动时预编译规则,在请求进入 location 前就已算出目标 upstream 名称。proxy_pass 后只需引用这个变量,就能命中对应 upstream 块,从而完成动态分流。
- map 必须写在
http块顶层,不可放在 server 或 location 内 - 映射目标必须是已定义的 upstream 名称(如
backend_v2),不是 IP 或 URL - proxy_pass 写法必须是
http://$upstream_name,后面不能带路径(否则变量失效) - 每个 upstream 块可独立配置负载均衡策略(weight、max_fails、backup 等)
按 URL 参数动态选后端
例如通过 ?backend=staging 切换环境:
http {
map $arg_backend $upstream_name {
default backend_prod;
"dev" backend_dev;
"staging" backend_staging;
"mock" backend_mock;
}
upstream backend_prod { server 10.0.1.100:8000; }
upstream backend_dev { server 10.0.1.200:8000 weight=3; }
upstream backend_staging { server 10.0.1.300:8000 max_fails=2; }
upstream backend_mock { server 127.0.0.1:3000; }
server {
location /api/ {
proxy_pass http://$upstream_name;
proxy_set_header Host $host;
}
}
}
按请求头做灰度或版本路由
适合 A/B 测试或 canary 发布,比如识别 X-Version: v2 或 X-Canary: true:
- 支持正则匹配:
~^v\d+$匹配 v1、v2 等格式 - 支持嵌套判断:先看 canary 头,无则 fallback 到 user-agent 规则
- 务必设
default,避免变量为空导致 502
注意事项与常见陷阱
proxy_pass 不允许 URI 中混用变量(如 http://$host/v1 会启动失败),这是由 Nginx 编译期解析机制决定的。若需改写路径,应配合 rewrite 或使用 proxy_pass 不带路径 + proxy_redirect 控制响应头。DNS 动态解析需额外配置 resolver,且仅适用于 proxy_pass http://$domain 这类纯域名变量形式,不适用于带端口或路径的写法。


















