nginx可通过geo+map+proxy_pass实现按内网网段(如192.168.193.0/24、192.168.194.0/24)动态路由:先用geo标记客户端网段,再用map映射至对应upstream名称,最后在proxy_pass中引用该变量完成差异化负载均衡。

要让 Nginx 针对不同内网网段(比如 192.168.193.0/24 和 192.168.194.0/24)做差异化负载均衡路由,核心不是靠 upstream 本身区分网段,而是结合 geo 指令 + map + proxy_pass 动态上游 实现请求来源识别与路由分发。Nginx 本身不支持“按客户端网段自动选不同 upstream 组”,但可通过配置逻辑精准达成这一目标。
用 geo 模块标记不同网段来源
在 http{} 块顶部定义地理区域变量,为不同网段打标签:
- 添加如下配置(注意放在所有 server 和 upstream 之前):
default "other";
192.168.193.0/24 "seg_a";
192.168.194.0/24 "seg_b";
}
该段会根据客户端真实 IP(需确保已正确获取,如使用 real_ip_header X-Forwarded-For; 并配置 set_real_ip_from)判断归属网段,并将结果存入变量 $client_net_segment。
用 map 映射网段到对应 upstream 名称
因为 proxy_pass 不支持直接写 http://$upstream_name(变量解析受限),需借助 map 将网段映射为可被 upstream 块引用的“逻辑上游名”:
- 继续在
http{}中添加:
default "default_backend";
"seg_a" "tomcat_seg_a";
"seg_b" "tomcat_seg_b";
}
这样,当请求来自 192.168.193.0/24 时,$backend_group 值为 tomcat_seg_a;来自 192.168.194.0/24 时则为 tomcat_seg_b。
定义多组 upstream 并在 location 中动态代理
分别定义适配不同网段的后端集群,再在 server 的 location 中通过变量选择转发目标:
- 定义两组 upstream(示例中均用 http 协议,端口按实际调整):
server 192.168.193.128:8080 weight=3;
server 192.168.193.129:8080;
}
upstream tomcat_seg_b {
server 192.168.194.128:8080;
server 192.168.194.129:8080 weight=2;
}
upstream default_backend {
server 127.0.0.1:8080;
}
- 在 server 块中使用变量代理(关键:必须用
proxy_pass http://$backend_group):
listen 80;
server_name _;
location / {
proxy_pass http://$backend_group;
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 后跟变量形式是支持的,但要求该变量值必须严格匹配某个已定义的 upstream 名称(大小写、拼写完全一致)。
验证与补充要点
完成配置后务必执行检查与重载:
-
nginx -t确保语法无误 -
nginx -s reload生效配置 - 用不同网段机器 curl 测试,例如:
– 从 192.168.193.10 执行curl http://192.168.192.130→ 应命中tomcat_seg_a中的节点
– 从 192.168.194.20 执行相同命令 → 应命中tomcat_seg_b - 若前端有 LVS 或云 LB,需确认是否透传了真实客户端 IP;否则
$remote_addr是上一跳地址,geo判断将失效











