ip_hash 无法实现指定用户IP到特定服务器的手动绑定,仅能通过哈希保证同一IP始终路由至同一后端;如需精准控制,应使用 map 或 geo 指令结合 upstream 实现。

ip_hash 是 Nginx 内置的负载均衡策略,它通过对客户端 IP 地址做哈希运算,再对后端服务器数量取模,把同一 IP 的请求始终映射到同一台后端节点上。但它不能直接指定某个用户 IP 固定转发到某台特定服务器(比如“192.168.1.100 → server A”这种人工绑定),这是它的设计限制。
ip_hash 的原理和默认行为
ip_hash 使用客户端 IPv4 地址的前 3 段(如 192.168.1.100)或整个 IPv6 地址做哈希,确保相同 IP 的请求落在同一台后端。它不支持手动配置 IP 到 server 的映射关系,也不识别用户登录态(如 cookie 或 token),只依赖 TCP 连接的源 IP。
- 如果用户经过 NAT、代理或 CDN,真实 IP 会丢失,导致 ip_hash 失效(所有用户被识别为同一个出口 IP)
- 后端节点增减会改变取模结果,导致部分 IP 映射关系重新分配(不满足严格一致性哈希)
- 不支持权重、健康检查自动剔除等高级特性(需配合 upstream 模块其他指令使用)
想实现“指定 IP → 指定节点”,可用的替代方案
若业务明确要求某些 IP 必须打到固定后端(例如灰度测试、客户专属服务节点),可结合 map + upstream + proxy_pass 实现精准控制:
- 用
map指令将特定 IP 映射为变量(如 $backend_server) - 定义多个 upstream 块(每个仅含一台 server),或在单个 upstream 中用
server ... down;控制可用性 - 在 location 中根据 $backend_server 变量选择不同 upstream 或直接指定 proxy_pass
示例片段:
map $remote_addr $target_upstream {
default "backend_default";
192.168.1.100 "backend_a";
203.0.113.5 "backend_b";
}
upstream backend_a { server 10.0.1.10:8080; }
upstream backend_b { server 10.0.1.11:8080; }
upstream backend_default { server 10.0.1.100:8080; server 10.0.1.101:8080; }
server {
location / {
proxy_pass http://$target_upstream;
...
}
}
进阶:更灵活的 IP 路由(如 CIDR、动态配置)
若需匹配网段或未来扩展性强,可:
- 用
geo指令定义 IP 区间映射(支持 CIDR,比 map 更适合网段) - 将 IP 规则写入外部文件,用 include 引入,便于运维更新
- 结合 Lua(通过 lua-resty-iputils 或自定义逻辑)做运行时判断,支持 header、cookie 等多维条件
注意点和常见坑
实际部署时要注意:
- 确保 $remote_addr 是真实用户 IP:需在前端代理(如 CDN、LB)正确设置 X-Real-IP / X-Forwarded-For,并在 Nginx 中用
set_real_ip_from和real_ip_header解析 - map 和 geo 指令必须放在 http 块顶层,不能在 server 或 location 内定义
- 修改 map/geo 后 reload 即可生效,无需重启 Nginx
- 避免把大量单 IP 写死在配置中——可读性差且难维护,建议按客户、地域、角色等维度分组映射


















