ip_hash是nginx原生轻量级会话粘滞方案,通过客户端真实ip哈希固定后端路由;需配置在upstream块首行、至少两台后端、禁用weight等参数,并配合real_ip_module还原真实ip,否则易导致雪崩或失效。

直接在 upstream 块开头加 ip_hash;,就能让同一客户端 IP 的请求始终打到同一台后端服务器上。这是 Nginx 原生最轻量的会话粘滞方案,不依赖 Redis 或数据库,但必须满足真实 IP 可用、后端多节点、无权重配置等前提。
基础配置写法要规范
ip_hash 必须写在 upstream 块第一行,不能缩进,也不能和其它负载策略混用:
- 后端列表至少写两台(单节点会报错或失效)
- 每行
server只写IP:PORT,不加http://、不带weight、backup、max_fails等参数 - 错误示例:
server 10.0.1.10:8080 weight=2;→ 启动直接失败 - 正确示例:
upstream backend {<br> ip_hash;<br> server 10.0.1.10:8080;<br> server 10.0.1.11:8080;<br> server 10.0.1.12:8080;<br>}<br>
确保拿到真实客户端 IP
如果前面有 CDN、WAF、Nginx 代理或云 LB,$remote_addr 默认是上一跳地址,所有请求会被哈希成同一个值,全部压到一台后端——这不是粘滞,是雪崩。
- 启用
real_ip_module(Nginx 默认编译包含) - 在
http块中声明可信代理段:set_real_ip_from 192.168.0.0/16;、set_real_ip_from 10.0.0.0/8; - 指定原始 IP 来源头:
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;
针对 WebSocket 场景需额外调优
WebSocket 是长连接,仅配 ip_hash 不够,Nginx 还得正确处理协议升级与心跳维持:
- 保留关键协议头:
proxy_set_header Upgrade $http_upgrade;、proxy_set_header Connection "upgrade"; - 延长超时时间:
proxy_read_timeout 3600;、proxy_send_timeout 3600; - 关闭缓冲:
proxy_buffering off;,防止帧被合并或延迟发送
清楚它的局限性,别硬套
ip_hash 不是万能钥匙,几个典型问题容易线上出事:
- IPv4 只取前 3 段哈希(
192.168.1.x全视为同一 IP),内网 NAT 下极易过载 - IPv6 地址哈希分布不均,/64 子网内常出现多个地址映射到同一后端
- 后端增减或宕机,哈希映射整体偏移,用户连接“漂移”,且无自动故障迁移
- 不感知健康状态:某台挂了,对应 IP 段请求仍持续发过去,直到超时才失败
若业务已接入 CDN、面向移动用户或要求高可用,建议改用 hash $cookie_route consistent;(Cookie 粘滞)或后端统一接入 Redis 存 Session。










