解决nginx负载均衡会话保持需结合业务选策略:①ip_hash绑定ip(轻量但受代理/nat影响);②cookie哈希(如hash $cookie_jsessionid)更精准;③redis统一存储session(解耦高可靠);④sticky cookie由nginx下发路由标识(适合无法改后端场景)。

解决 Nginx 负载均衡集群中的会话保持问题,核心在于让同一用户的多次请求能持续命中同一台后端服务器,或确保各服务器能共享会话状态。不能只靠轮询,得结合业务场景选合适策略——不是所有方案都通用,关键看 IP 是否稳定、是否允许改造应用、有没有共享存储能力。
用 ip_hash 绑定客户端 IP(轻量、免改造)
这是 Nginx 原生支持的最简方案:对客户端真实 IP 做哈希,固定路由到某台后端。配置只需在 upstream 块开头加一行 ip_hash;:
- IPv4 只取前 3 段哈希(192.168.1.x 全视为同一 IP),适合内网固定 IP 场景
- 不支持 weight、backup 等参数,加了会导致 Nginx 启动失败
- 前端有 CDN/WAF/代理时,$remote_addr 是上一跳地址,必须配合 real_ip_module 还原真实 IP:
– 在 http 块中声明可信段:set_real_ip_from 10.0.0.0/8;
– 在 location 中透传:proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - 后端列表变动(如扩容、临时 down 掉一台),哈希映射整体偏移,大量用户会“漂移”
用 Cookie 哈希替代 IP(更精准、抗 NAT)
避免 IP 变更导致会话中断,尤其适合公网用户(如手机切 WiFi/4G)。Nginx 可基于已有会话 Cookie(如 JSESSIONID)做一致性哈希:
- 配置示例:hash $cookie_JSESSIONID consistent;(放在 upstream 内,无需第三方模块)
- 首次请求无该 Cookie 时,会走默认轮询;后续带 Cookie 的请求才被哈希绑定
- 比 ip_hash 更稳,不受 NAT、代理、IP 池变化影响
- 要求后端应用生成并返回标准会话 Cookie(如 Tomcat 默认的 JSESSIONID)
后端统一接入 Redis 存储 Session(解耦、高可靠)
彻底跳出“绑定服务器”的思路,让所有后端读写同一份会话数据。这不是 Nginx 配置能单独解决的,需后端配合:
- PHP:设 session.save_handler = redis,并配置 redis host/port
- Java(Spring Boot):引入 spring-session-data-redis,自动接管 HttpSession
- Node.js:用 express-session + connect-redis 中间件
- Nginx 本身不参与会话管理,只负责反向代理,负载策略可回归轮询或 least_conn
- 优势明显:后端任意宕机都不丢会话,扩容缩容无感知,适合中大型业务
用 sticky cookie 插入路由标识(无需后端改代码)
由 Nginx 主动下发一个路由 Cookie(如 srv_id),后续请求按此 Cookie 分发。需启用第三方模块 nginx-sticky-module:
- 配置示例:sticky cookie srv_id expires=1h domain=.example.com;
- 首次请求无 Cookie,Nginx 用轮询选一台后端,并在响应头中 Set-Cookie
- 后续请求携带该 Cookie,Nginx 直接查表转发,不依赖后端生成
- 注意:需编译 Nginx 时加入该模块,不适用于官方预编译包;Cookie 值明文或加密可选
- 适合无法修改后端逻辑、又需要强会话粘性的场景(如遗留系统)











