ip_hash可实现客户端ip会话保持,但需确保真实ip、后端稳定及严格配置:必须首行无缩进、仅限upstream块、至少两台server、禁用weight等参数,且需通过set_real_ip_from等还原真实ip,否则易失效。

直接在 upstream 块第一行写 ip_hash;,就能让同一客户端 IP 的请求始终打到同一台后端服务器。但它不是“配了就稳”,关键得保证 IP 真实、后端稳定、配置合规,否则会话照样漂移。
基础配置必须严格遵循的规则
ip_hash 只能出现在 upstream 块的首行,不能缩进,不能和其它 hash 指令共存,也不能加任何修饰符:
- upstream 至少定义两台后端(单节点不生效)
- server 行只写
IP:PORT,不加http://、路径或协议前缀 - 绝对不能加
weight、backup、down等参数,否则 Nginx 启动失败 - IPv4 地址默认取前三段哈希(如
192.168.1.100和192.168.1.255视为同一 IP)
示例:
upstream backend {
ip_hash;
server 10.0.1.10:8080;
server 10.0.1.11:8080;
server 10.0.1.12:8080;
}
必须还原真实客户端 IP
如果前端有 CDN、WAF、Nginx 代理或多层 LB,$remote_addr 就是上一跳地址,所有用户会被哈希到同一台后端,策略完全失效。
需在 http 块中配置真实 IP 解析:
- 用
set_real_ip_from声明可信代理网段(如192.168.0.0/16、10.0.0.0/8) - 用
real_ip_header X-Forwarded-For指定头字段来源 - 在
location中透传头信息:proxy_set_header X-Real-IP $remote_addr;和proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
避开几个高频失效场景
ip_hash 映射关系非常脆弱,以下任一变动都会导致大量用户会话漂移:
- upstream 中增删 server 节点(哪怕只是临时
down一台) - 调整 server 行顺序(包括换行位置、注释插入等细微变化)
- 用户从移动网络切换 WiFi,IP 改变,Session 找不到
- 内网大量设备走 NAT 出口,多个用户共享同一出口 IP,全被哈希到同一台后端,造成负载倾斜
更稳的替代方案建议
当业务规模上升或稳定性要求提高时,应逐步迁出 ip_hash:
- 改用 Cookie 哈希:
hash $cookie_JSESSIONID consistent;,抗代理、NAT 和 IP 变更 - 后端统一接入 Redis 存 Session(如 Spring Boot 配置
spring.session.store-type=redis),彻底解耦路由与状态 - TCP/UDP 四层转发必须用
stream模块 +hash $remote_addr consistent;,ip_hash 在 stream 中不生效











