ip_hash是nginx原生ip哈希会话保持机制,需在upstream块首行配置、依赖真实客户端ip、不支持weight/backup,易受代理/nat/后端变动影响,推荐结合real_ip_module与cookie哈希或redis方案升级。

ip_hash 是 Nginx 原生支持的会话保持方式,靠客户端 IP 哈希固定路由到同一后端,配置简单、无需额外模块或 Cookie 依赖。但它不是万能解——效果好坏,高度取决于网络环境是否匹配其设计前提。真正有效的配置,不只是一行 ip_hash;,而是围绕真实 IP 获取、后端稳定性、哈希一致性三个关键点做系统性优化。
确保 Nginx 拿到真实的客户端 IP
前端若有 CDN、WAF、云 LB 或多层代理,$remote_addr 默认是上一跳地址,所有请求会被哈希到同一台后端,导致负载严重倾斜甚至完全失效。
- 在
http块中启用real_ip_module,明确声明可信代理网段:
set_real_ip_from 192.168.0.0/16;
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 172.16.0.0/12;
real_ip_header X-Forwarded-For;
- 在反向代理的
location中透传真实 IP 头:
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- 验证是否生效:用
curl -H "X-Forwarded-For: 203.203.203.1" http://your-domain/测试,检查日志中$remote_addr是否为该 IP
严格遵循 ip_hash 配置规范
看似简单的一行指令,违反任一规则都会导致启动失败或行为异常。
-
ip_hash;必须放在upstream块第一行,顶格书写,不能缩进,不能与其他hash指令(如hash $cookie_jsessionid)共存 - upstream 至少定义两台后端,不能只写
localhost或单节点;server 行仅写IP:PORT,不加http://或路径 - 严禁使用
weight、backup、down等参数——加了会导致 Nginx 启动报错 - IPv4 地址默认取前三段哈希(如
192.168.1.100和192.168.1.255视为同一 IP),内网 NAT 环境下易造成单节点过载
规避会话漂移与负载失衡风险
ip_hash 的映射关系脆弱,后端列表变动或网络结构变化会直接破坏一致性。
- 避免频繁增删后端节点:扩容或缩容会触发全量重散列,大量用户请求跳转,Session 丢失
- 临时下线某台 server 时,优先用
down标记而非直接删除配置(注意:down本身不被 ip_hash 支持,需改用健康检查模块或商业版) - 若业务已出现 NAT、代理或移动网络切换(4G/WiFi),说明 IP 不稳定,此时 ip_hash 效果有限,应转向更鲁棒的方案
更稳的替代方案建议
当业务规模上升或对可用性要求提高,建议逐步过渡到抗干扰更强的机制。
- Cookie 哈希:用
hash $cookie_JSESSIONID consistent;替代 ip_hash,不受代理和 NAT 影响,首次请求后即绑定,适合 Java/Spring Boot 等主流框架 - Session 统一存储:后端接入 Redis 存储 Session(如 Spring Boot 配置
spring.session.store-type=redis),彻底解耦路由与状态,允许任意扩缩容 - TCP/UDP 四层场景:ip_hash 不生效,必须改用
stream模块 +hash $remote_addr consistent;











