ip_hash通过客户端ip哈希固定路由至同一后端,实现会话保持;需确保真实ip识别、upstream严格配置(顶格首行、至少两节点、禁用weight等)、规避nat与后端变更导致的漂移。

Nginx 的 ip_hash 本身不维护“客户端连接唯一性”,它只是把同一客户端 IP 的请求固定路由到同一台后端服务器,从而在无共享 Session 存储的前提下,让应用层的会话状态(如 Cookie、内存 Session)自然命中原节点。这种“连接唯一性”是间接达成的,依赖 IP 稳定性和配置严谨性。
以下几点直接决定它能否在集群中可靠生效:
必须确保真实客户端 IP 可被识别
Nginx 默认用 $remote_addr 做哈希,但若前端有 CDN、WAF、LVS 或其他 Nginx 代理,这个变量会变成中间代理的 IP,导致所有用户哈希到同一台后端。
你需要:
- 在
http块中声明可信代理段: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;
正确配置 upstream 块结构
ip_hash 是严格模式指令,容错率低:
- 必须放在
upstream块第一行,顶格写,不能缩进 - 后端至少定义两台服务器(单节点会失效)
-
server行只写IP:PORT或域名:PORT,不能带http://、路径或协议前缀 -
禁止使用
weight、backup、down、max_fails等参数——加了会导致 Nginx 启动失败或静默忽略
示例:
upstream app_cluster {
ip_hash;
server 10.1.1.10:8080;
server 10.1.1.11:8080;
server 10.1.1.12:8080;
}
理解 IPv4 哈希行为与 NAT 风险
- IPv4 地址仅取前三段做哈希(如
192.168.1.100和192.168.1.254被视为相同 IP) - 内网用户经 NAT 出口时,几十甚至上百人共用一个出口 IP,全部请求会打到同一台后端,极易造成单点过载
- IPv6 使用完整地址哈希,更精准,但需确认客户端和网络链路全程支持 IPv6 透传
避免后端变更引发会话漂移
ip_hash 的映射关系是全局静态哈希表,依赖后端列表顺序和数量:
- 新增一台 server → 所有哈希结果重分配,约 1/N 用户会漂移
- 下线一台 server(哪怕标为
down)→ 剩余节点重新取模,原有 IP 映射关系整体偏移 - 临时故障未触发
max_fails(因ip_hash不兼容该参数)→ 请求仍持续发往异常节点,直到手动down
所以,它适合后端规模稳定、扩缩容频率低的场景,比如 MinIO 分片上传、内部管理系统等。
不复杂但容易忽略











