ip_hash通过哈希客户端IP并固定路由至同一后端服务器,使Session保留在该机内存中,从而避免登录态丢失;但其本质是会话保持而非分布式Session方案,存在IP变更失效、NAT冲突、扩缩容重哈希等缺陷。

Nginx 的 ip_hash 并不真正解决 Session 共享,而是通过会话保持(Session Persistence)绕过共享问题:让同一个客户端 IP 始终打到同一台后端服务器,从而复用该服务器内存中已有的登录态(如 JSESSIONID、PHPSESSID),避免因请求跳转导致重复登录。
它不是分布式 Session 方案,而是一种“绑定式临时缓解手段”。
ip_hash 是怎么做到登录态不丢失的
- Nginx 对客户端真实 IPv4 地址(前 3 段)做哈希运算,再对后端服务器数量取模,结果固定指向某台机器
- 只要用户 IP 不变、后端列表没增删,后续所有请求都落在同一台应用服务器上
- 登录成功后生成的 Session 自然保留在那台机器的 JVM 或 PHP 内存里,后续请求能直接读取,无需跨节点查找
使用前提和关键配置要点
- 必须确保
$remote_addr是真实用户 IP:- 若前端有 CDN、WAF 或代理,需启用
real_ip_module,配合set_real_ip_from和real_ip_header正确还原源 IP
- 若前端有 CDN、WAF 或代理,需启用
-
upstream块中必须把ip_hash;放在server行之前,否则不生效 - 不能与
weight同时使用,否则 Nginx 启动失败 - 示例配置:
upstream backend { ip_hash; server 192.168.1.101:8080; server 192.168.1.102:8080; server 192.168.1.103:8080; }
它为什么在登录场景“看起来有效”
- 遗留系统常把 Session 存在单机内存中,未接入 Redis 或数据库
- 轮询策略下,第二次请求可能落到无 Session 的节点,触发登出或重定向登录页
-
ip_hash让用户“始终回到老地方”,相当于给 Session 加了一层路由保障
但它掩盖了架构风险,实际要注意这些坑
- 用户换网络(WiFi → 4G)、重启路由器、走企业 NAT,IP 变了 → 登录态立即失效
- 校园网/公司出口多个用户共用一个公网 IP → 全被压到同一台后端,引发热点和超载
- 扩容一台机器或下线一台,哈希空间重排 → 大量用户被重新分配,集体掉登录
- 原生
ip_hash不支持完整 IPv6(仅取前 64 位),双栈环境一致性难保证
更靠谱的长期解法
- 把 Session 存到共享存储:Spring Session + Redis、Tomcat RedisSessionManager
- 改为无状态鉴权:JWT + 前端本地存储 token,后端只校验签名,不依赖 Session
- 用 Cookie 哈希代替 IP 哈希:
hash $cookie_jsessionid;(前提是 Cookie 可靠且防篡改) - 配合健康检查:加上
max_fails=3 fail_timeout=30s,避免故障节点持续接收流量
不复杂但容易忽略。


















