ip hash 在 nginx 中是依赖真实客户端 ip 的会话保持机制,需确保 $remote_addr 为真实出口 ip、规避 nat 导致的会话倾斜、维持 upstream 列表稳定,并配套日志与健康检查实现可观测性。

IP Hash 在 Nginx 中不是“保障稳定交互”的万能钥匙,而是一种有明确适用边界的会话保持手段——它能让同一客户端 IP 的请求始终落到同一台后端服务器,从而避免因 Session 未共享导致的登录跳转、购物车丢失等问题,但前提是真实 IP 可靠、后端拓扑稳定、网络环境可控。
确保真实客户端 IP 被正确识别
如果用户经过 CDN、WAF、LVS 或上层 Nginx 代理,$remote_addr 拿到的往往是中间节点 IP,哈希就完全失效。必须配合 real_ip_module 还原原始地址:
- 在 http 块中配置可信代理段:
set_real_ip_from 192.168.0.0/16;(按实际代理网段填写) - 指定真实 IP 来源头:
real_ip_header X-Forwarded-For;或X-Real-IP(需与上游一致) - 验证是否生效:在日志中加
$http_x_forwarded_for和$remote_addr对比,确认哈希对象是用户真实出口 IP
规避 NAT 和 IP 变更带来的会话断裂
企业内网、校园网、移动运营商普遍使用 NAT,大量用户共用一个公网 IP,IP Hash 会把所有流量压向单台后端,造成严重倾斜甚至雪崩:
- 若业务面向这类用户,不建议直接启用 ip_hash;可改用
hash $cookie_jsessionid consistent;(需应用写入可靠 Cookie) - 对移动端用户,Wi-Fi 切 4G/5G 会导致 IP 变更,会话立即中断;此时应推动架构升级为 JWT 或 Redis 共享 Session
- 测试时务必用不同公网出口(如手机热点、家庭宽带、公司网络)模拟,不能只在本地反复刷新
维持 upstream 列表稳定性,防止哈希重散列
ip_hash 的映射关系依赖后端服务器数量和顺序。任意增删节点或调整顺序,所有已有 IP 的路由都会重新计算:
- 扩容时避免直接新增 server 行,可先用
down标记旧节点,再逐步上线新节点并观察流量分布 - 缩容前建议先将目标 server 设为
down,等自然流量衰减后再移除配置,减少突变影响 - 严禁在 ip_hash 块中混用
weight、backup,Nginx 启动会报错;如需备用节点,可用server ... down;手动触发切换
配套可观测性与基础防护
光配好 ip_hash 不够,必须通过日志和健康检查形成闭环:
- 日志格式中加入
$upstream_addr和$remote_addr,便于追踪某 IP 是否长期落在同一台后端 - 为每台 server 配置
max_fails=2 fail_timeout=10s,让 Nginx 在连续失败后临时屏蔽故障节点(注意:屏蔽期间该 IP 请求会返回 502) - 搭配
proxy_next_upstream error timeout http_502;,在上游异常时尝试 fallback(但 ip_hash 下 fallback 仍受限于哈希结果)











