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

在 Nginx 中使用 ip_hash 是实现简单会话保持(Session Persistence)的常用方式,它能让同一客户端 IP 的请求始终被转发到上游服务器集群中的同一台后端节点。这种方式适合无状态服务或后端已共享 Session(如 Redis 存储)的场景,但不适用于 IP 经常变化的用户(如移动网络、NAT 环境)。
启用 ip_hash 的基本配置
只需在 upstream 块中添加 ip_hash; 指令即可开启基于客户端 IP 的哈希路由:
upstream backend {
ip_hash;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
注意:ip_hash 会自动忽略 IPv4 的最后一个字节(即 /24 网段),对 IPv6 则取前 64 位做哈希,以缓解同一局域网用户被散列到不同后端的问题。
ip_hash 的限制与注意事项
- 上游服务器列表不能动态增删——一旦添加或删除
server行,哈希结果可能整体偏移,导致大量用户会话“漂移” - 不支持权重(
weight)、健康检查失败自动剔除(max_fails、fail_timeout)等参数与ip_hash共存(Nginx 会报错) - 若某台后端宕机,Nginx 会临时将其从哈希环中剔除,但剩余节点的映射关系不变,用户请求会重定向到其他可用节点——这属于“被动容错”,不会主动重平衡
- 客户端真实 IP 必须能被 Nginx 正确获取;若前端有 LVS、CDN 或代理,需配合
set_real_ip_from和real_ip_header设置可信来源,否则哈希基于代理 IP,失去意义
替代方案:更灵活的会话保持方式
当需要支持权重、健康检查或避免 IP 变化影响时,可考虑:
-
sticky cookie(Nginx Plus 或开源版 + 模块):用
sticky cookie(需 nginx-sticky-module)或 Nginx Plus 的sticky learn,基于 Set-Cookie 维持会话 -
hash $cookie_jsessionid:如果应用本身已通过 JSESSIONID 等 Cookie 标识会话,可按 Cookie 值哈希:
hash $cookie_jsessionid consistent;(推荐加consistent使用一致性哈希减少漂移) - 第三方模块如 nginx-upstream-jvm-route:适用于 Tomcat 集群,按 JSESSIONID 路由并自动处理 failover
验证 ip_hash 是否生效
可通过日志或简单测试确认:
- 在 upstream 中为各 server 添加
down或临时注释某台,观察同一 IP 的请求是否始终落在其余存活节点上 - 在 access_log 中记录
$remote_addr和$upstream_addr,发起多次请求比对是否固定 - 使用 curl 多次访问,配合
curl -s -w "\n%{url_effective}\n" -o /dev/null http://your-domain/并查看后端响应头中的标识(如自定义 X-Backend-ID)











