nginx 的 map 指令通过请求头动态生成上游变量实现路由,需定义在 http 块中,配合 upstream 和 proxy_pass 使用;支持正则、默认值,proxy_pass 必须为 http://$variable 形式且不带路径。

Nginx 的 map 指令本身不直接转发请求,但它能根据请求头(如 Host、X-Cluster-ID、User-Agent 等)动态生成变量,再配合 upstream 和 proxy_pass 实现后端集群的动态路由。关键在于“变量驱动选择”,而非在 map 里写转发逻辑。
用 map 提取并映射请求头到上游名称
map 必须定义在 http 块中,它将输入值(如请求头)映射为一个自定义变量(如 $backend_cluster)。支持正则匹配、默认值和嵌套判断:
http {
# 根据 X-Cluster-ID 请求头选择集群
map $http_x_cluster_id $backend_cluster {
default cluster_default;
"prod-a" cluster_prod_a;
"prod-b" cluster_prod_b;
~^staging-\d+$ cluster_staging;
~^canary-.*$ cluster_canary;
}
<pre class="brush:php;toolbar:false;"># 也可组合多个头,例如按 region + env 联合判断(需借助更复杂变量或 Lua,纯 map 仅支持单输入)}
定义多个 upstream 集群
每个集群对应一组后端服务器,名称需与 map 中输出的变量值严格一致:
upstream cluster_default {
server 10.0.1.10:8080;
server 10.0.1.11:8080;
}
<p>upstream cluster_prod_a {
server 10.0.2.20:8080;
server 10.0.2.21:8080;
}</p><p>upstream cluster_canary {
server 10.0.3.30:8080 weight=5;
server 10.0.1.10:8080 weight=1; # 混流到默认集群作兜底
}</p>在 location 中用变量驱动 proxy_pass
proxy_pass 支持变量形式(注意:不能带 URI 路径,否则会丢弃原始请求路径):
- ✅ 正确写法:
proxy_pass http://$backend_cluster; - ❌ 错误写法:
proxy_pass http://$backend_cluster/api;—— 这会导致路径被重写,且变量不生效 - 若需固定路径前缀,应在
location路径中定义,由 Nginx 自动拼接
补充建议与注意事项
-
map是惰性求值的,只在变量首次被引用时执行,性能开销极小 - 请求头名统一转为小写加下划线格式:
X-Forwarded-For→$http_x_forwarded_for - 空头或未匹配项会走
default分支,务必设置合理兜底,避免 502 - 如需更灵活逻辑(如 header 存在性判断、多条件与/或),可搭配
if+set,但注意if在location外不可用;复杂场景推荐 OpenResty + Lua











