直接在upstream块首行写ip_hash;即可启用客户端IP会话保持,但必须满足:置于首行、至少两台后端、禁用weight/backup、透传真实IP、避免NAT干扰,否则配置无效或启动失败。

直接在 upstream 块第一行写 ip_hash; 就能启用基于客户端 IP 的会话保持,但必须满足几个硬性条件,否则配置无效甚至导致 Nginx 启动失败。
基础配置写法(必须严格遵循)
ip_hash 只能出现在 upstream 块的首行,不能缩进,不能和其它负载策略共存:
- upstream 至少要定义两台后端服务器(单节点不生效)
- server 行只写
IP:PORT,不加http://或路径 - 不能出现
weight、backup、down等参数,加了会报错退出
示例:
upstream backend {
ip_hash;
server 10.0.1.10:8080;
server 10.0.1.11:8080;
server 10.0.1.12:8080;
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
确保拿到真实客户端 IP
如果请求经过 CDN、WAF、NAT 或前置代理,$remote_addr 默认是上一跳地址,所有用户会被哈希到同一台后端——看起来“配了没用”。需配合 real_ip_module 还原真实 IP:
- 在
http块中声明可信代理网段:set_real_ip_from 192.168.0.0/16;(按实际代理 IP 段填写) - 指定真实 IP 来源头字段:
real_ip_header X-Forwarded-For; - 在
location中透传头信息,确保后端也能拿到:proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
注意 IPv4 哈希的隐含行为
Nginx 对 IPv4 地址只取前三段做哈希(例如 192.168.1.100 和 192.168.1.200 被视为同一 IP),这在内网 NAT 环境下极易造成单台后端过载:
- 企业出口、校园网、运营商共享 IP 场景下,大量用户被绑定到同一台后端
- IPv6 默认使用前 64 位哈希;如需完整地址一致性,需确认后端服务兼容性
哪些变动会导致会话突然漂移
ip_hash 映射不是静态绑定,以下任一操作都会触发全量重散列,已有用户会话大概率中断:
- upstream 中增删任意一台 server
- 调整 server 行顺序(包括换行、空格、注释位置变化)
- 某台 server 被临时标记为
down,剩余节点哈希索引整体偏移 - 用户网络切换(如手机从 4G 切 WiFi),IP 改变后无法命中原会话


















