Nginx 的 map 指令是实现基于来源 IP 动态路由最灵活、低侵入的方式,通过 geo 模块匹配 IP 段并映射为 upstream 名称变量,再在 proxy_pass 中引用该变量完成动态转发,推荐配合 realip 获取真实客户端 IP 并注意变量命名与 upstream 严格一致。

Nginx 的 map 指令是实现基于来源 IP 动态路由最灵活、低侵入的方式之一。它不依赖第三方模块,原生支持,且可与 geo、realip 等模块配合,在真实业务中广泛用于灰度发布、地域调度、内外网隔离等场景。
核心思路是:把客户端 IP 映射为一个变量(如 $upstream_name),再在 proxy_pass 中引用该变量,指向对应 upstream 块。
一、基础配置:用 geo + map 绑定 IP 段到 upstream 名称
`geo` 模块适合做 CIDR 匹配(如内网段、特定机房 IP),比纯正则更高效:# 在 http 块顶层定义
geo $client_network {
default 0;
10.0.0.0/8 1; # 内网 A 段
172.16.0.0/12 2; # 内网 B 段
192.168.0.0/16 3; # 内网 C 段
203.0.113.10 4; # 某个测试公网 IP
}
map $client_network $backend_upstream {
default "prod_backend";
1 "intranet_a_backend";
2 "intranet_b_backend";
3 "intranet_c_backend";
4 "test_backend";
}这样,每个 IP 段被映射为一个字符串值,后续可直接用于 proxy_pass http://$backend_upstream。
二、进阶用法:结合 realip 获取真实客户端 IP
若 Nginx 前有 CDN 或 LB,需先还原真实 IP,否则 `$remote_addr` 是代理地址:# 在 http 块中启用 realip(假设可信代理为 10.10.0.0/16)
set_real_ip_from 10.10.0.0/16;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
# 此时 $remote_addr 已更新为真实客户端 IP
geo $is_internal_ip {
default 0;
10.0.0.0/8 1;
172.16.0.0/12 1;
192.168.0.0/16 1;
}
map $is_internal_ip $backend_upstream {
0 "public_backend";
1 "internal_backend";
}注意:X-Forwarded-For 头可能被伪造,务必只信任已知代理 IP 段,并开启 real_ip_recursive on 安全解析。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
三、动态 proxy_pass 的关键写法
在 `location` 块中使用变量名拼接 upstream,必须确保变量值**严格等于 upstream 块名称**(含大小写、下划线):upstream internal_backend {
server 10.0.1.10:8080;
server 10.0.1.11:8080;
}
upstream public_backend {
server 10.0.2.20:8080;
server 10.0.2.21:8080;
}
server {
listen 80;
location / {
proxy_pass http://$backend_upstream;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}⚠️ 注意事项:
- 变量不能带引号,
proxy_pass http://$backend_upstream;✅;proxy_pass "http://$backend_upstream";❌(语法错误) - upstream 名称中避免空格、短横线(
-),推荐全小写+下划线 - 若变量为空或未匹配,Nginx 会报
no resolver defined to resolve ...错误,建议default值设为稳定可用的 upstream
四、替代方案对比:map vs if + geo vs rewrite
| 方式 | 是否推荐 | 原因 | |------|----------|------| | `map` + `geo` | ✅ 强烈推荐 | 编译期构建查找表,性能高;逻辑清晰;支持嵌套和默认兜底 | | `if ($remote_addr ~ ...) { set $upstream ... }` | ⚠️ 不推荐 | `if` 在 location 外不安全;正则匹配开销大;易出错 | | `rewrite ... break` 配合不同 location | ❌ 不适用 | 路由逻辑分散,维护成本高,无法复用 upstream |map 是声明式、无副作用、可静态验证的最佳实践。
不复杂但容易忽略细节


















