Nginx中的ip_hash
ip_hash 是 Nginx 负载均衡中用于 会话保持(Session Persistence) 的算法,其核心原理是通过客户端 IP 地址的哈希值,将同一客户端的请求固定转发到同一台后端服务器。
1. 核心原理
- 哈希计算:
- Nginx 将客户端的 IPv4 地址前三个字节(C类地址) 或整个 IPv6 地址 作为输入,计算哈希值。
- 哈希算法为 CRC32 或 MurmurHash2(取决于 Nginx 版本)。
- 公式简化表示:hash = hash_function(client_ip) % server_count
- 服务器选择:
- 根据哈希值对后端服务器数量取模,确定目标服务器。
- 示例:
a. 客户端 IP 为 192.168.1.100,哈希值为 2103985966,后端有 3 台服务器。
b. 2103985966 % 3 = 1 → 请求被分配到第 2 台服务器(索引从 0 开始)。
2. 配置示例
http {
upstream backend {
ip_hash; # 启用 IP 哈希算法
server 10.0.0.1; # 后端服务器 1
server 10.0.0.2; # 后端服务器 2
server 10.0.0.3; # 后端服务器 3
}
server {
location / {
proxy_pass http://backend;
}
}
}
3. 关键特性
- 会话保持:
同一客户端的请求始终由同一台服务器处理,适用于需要保持会话状态的应用(如登录状态、购物车)。 - 无状态性:
无需在后端服务器之间同步会话数据(如 Session),降低架构复杂度。 - 权重支持:
在 Nginx 商业版(NGINX Plus)中,ip_hash 可与 weight 参数结合,但开源版默认忽略权重。
4. 局限性
- 服务器数量变化问题:
若后端服务器数量增减(如扩容/缩容),哈希取模结果会变化,导致大量客户端重新路由到不同服务器,会话丢失。 - IP 段分布不均:
如果客户端 IP 集中在同一网段(如企业 NAT 出口 IP),哈希结果可能倾斜,导致负载不均衡。 - 代理层 IP 干扰:
若客户端经过代理(如 CDN、反向代理),Nginx 获取的可能是代理服务器 IP,而非真实客户端 IP,需通过 proxy_set_header X-Real-IP $remote_addr; 传递真实 IP。
5. 替代方案
方案 | 原理 | 适用场景 |
ip_hash | 基于客户端 IP 哈希固定服务器 | 简单会话保持,无复杂权重需求 |
hash $cookie_xxx | 基于 Cookie 值哈希固定服务器 | 需精细控制会话(如特定用户绑定) |
sticky cookie | 插入 Cookie 标识服务器(需模块支持) | 高可用性要求,支持服务器动态变化 |
一致性哈希 | 哈希环减少服务器变动影响(需第三方模块) | 大规模集群,需最小化会话迁移成本 |
6. 最佳实践
- 获取真实客户端 IP:
确保 Nginx 配置中通过 X-Forwarded-For 或 X-Real-IP 获取真实 IP(尤其在代理链中)。 - 监控负载均衡:
使用 nginx-module-vts 等工具监控后端服务器的请求分布,避免哈希倾斜。 - 动态扩缩容策略:
若需频繁调整服务器数量,建议使用 一致性哈希(如 nginx-sticky-module)或基于 Cookie 的会话保持。
上一篇:nginx反向代理配置
下一篇:Nginx Header 整理