应放弃ip_hash,改用cookie实现稳定会话粘滞;后端下发route cookie,nginx基于$cookie_route做一致性哈希路由,并配合redis同步session或jwt无状态认证。

Nginx 的 ip_hash 本身不适用于客户端 IP 频繁变动的场景——它不是为这类情况设计的,强行使用反而会加剧会话丢失。真正有效的应对方式,是放弃依赖 IP,转而用更稳定、可携带的身份标识来维持会话粘滞。
移动端或 NAT 环境下 IP 变动的根本原因
4G/5G 与 Wi-Fi 切换、基站重选、运营商 NAT 池轮转,都会让 $remote_addr 在毫秒级内突变。IPv4 即使只取前三段哈希,也无法覆盖跨网段跳变(比如从 112.68.10.x 直接切到 218.202.15.x),更无法区分真实用户(成百上千人共用一个出口 IP)。
推荐用 Cookie 实现稳定粘滞
后端在登录成功时下发一个带路由信息的 Cookie(如 ROUTE=server-2),Nginx 依据该值做一致性哈希路由:
- upstream 中配置:
upstream backend { hash $cookie_ROUTE consistent; server 10.0.0.1:8080; server 10.0.0.2:8080; server 10.0.0.3:8080; } - 后端响应头需包含:
Set-Cookie: ROUTE=server-2; Path=/; HttpOnly; Secure - 前端发起请求时确保携带 Cookie(如 fetch 加
credentials: 'include')
这种方式完全脱离 IP,只要用户没清 Cookie,路由就稳定;增减后端节点时 consistent 参数还能最小化漂移。
若必须保留 ip_hash,仅限极少数可控场景
比如企业定制 App + 固定 APN + 内网部署,此时可配合:
-
set_real_ip_from和real_ip_header X-Forwarded-For尽量还原真实设备 IP - 后端将 Session ID 同步写入 Redis,Nginx 故障跳转后尝试按 Cookie 中的
JSESSIONID查 Redis 恢复状态
彻底解耦会话的长期方向
把登录态交给无状态机制:JWT 全局校验、Redis 统一存储 Session、或前端持久化 Token + 后端校验签名。这样连粘滞都不需要,负载均衡可直接用 least_conn 或加权轮询,扩展性和容错性都更好。
不复杂但容易忽略











