Nginx 的 map 指令可在 http 块中基于 host、请求头或路径预定义变量映射,实现动态转发;需设 default 防空值,配合 proxy_pass 使用,适用于灰度发布、多租户路由等场景。

想用 Nginx 实现根据请求头、域名或路径动态转发到不同后端?map 指令是轻量又可靠的选择,它不依赖 Lua 或外部模块,纯原生配置就能完成条件映射,适合灰度发布、多租户路由、A/B 测试等场景。
理解 map 的作用机制
map 不是直接处理请求,而是定义变量映射关系。它在 server 或 http 块中预计算一个变量值(比如 $backend),后续在 proxy_pass 中引用即可。Nginx 在每次请求时根据源字段(如 $host、$http_x_env)查表赋值,过程高效且无运行时开销。
注意两点:
- map 块必须写在 http{} 内,不能放在 server{} 里;
- 默认不匹配时变量为空,建议用 default 显式设默认值,避免 proxy_pass 指向空地址报错。
按 Host 或子域名分发到不同服务
适用于多租户 SaaS 或灰度环境隔离:
- 在 http{} 中定义映射:
default "127.0.0.1:8080";
app1.example.com "10.0.1.10:3000";
app2.example.com "10.0.1.11:3000";
staging.example.com "10.0.1.20:8080";
}
- 在 server{} 中使用:
proxy_pass http://$backend;
proxy_set_header Host $host;
}
结合请求头做灰度或环境路由
例如根据 X-Env: staging 将部分请求打到测试集群:
- 定义基于请求头的映射:
default "127.0.0.1:8080";
"staging" "10.0.1.50:8080";
"canary" "10.0.1.51:8080";
}
- 配合 proxy_set_header 透传原始头(可选):
proxy_pass http://$backend;
proxy_set_header X-Original-Env $http_x_env;
}
路径前缀 + 变量组合实现细粒度路由
比如 /api/v1/users → 转发到 users-svc,/api/v1/orders → 转发到 orders-svc:
- 先用正则捕获路径段,再 map 映射:
default "default-svc";
~^/api/v1/users/ "users-svc";
~^/api/v1/orders/ "orders-svc";
~^/api/v1/products/ "products-svc";
}
upstream users-svc { server 10.0.2.10:8001; }
upstream orders-svc { server 10.0.2.11:8002; }
upstream products-svc { server 10.0.2.12:8003; }
- 转发逻辑:
proxy_pass http://$service;
}










