nginx基于cookie的会话保持核心是确保同一用户后续请求始终路由至同一后端服务器,以避免session丢失;优先选用nginx-sticky-module-ng模块自动注入srv_id cookie,或在无法编译时用hash $cookie_jsessionid consistent依赖已有业务cookie实现软粘性。

在 Nginx 负载均衡中,基于 Cookie 实现会话持久化,核心是让同一用户后续请求始终路由到同一台后端服务器——尤其当 Session 存储在本地内存(如 Tomcat 默认 HttpSession)而未使用 Redis 等共享存储时,这是避免反复登录、购物车丢失的关键手段。
为什么优先选 Cookie 方案而非 ip_hash
ip_hash 看似简单,但实际问题突出:企业出口或移动网络常为 NAT 环境,大量用户共用一个公网 IP,导致流量全部压向单台后端;客户端切换网络(4G→WiFi)或经 CDN/代理后,真实 IP 被掩盖,会话直接中断。Cookie 方案绕开了 IP 变动和地址复用问题,更贴近用户粒度。
推荐方案:nginx-sticky-module-ng(免业务改造)
这是目前最成熟、轻量、广泛验证的开源 sticky 模块,无需修改后端代码,自动注入并识别路由 Cookie。
- 编译安装:下载模块源码(如 nginx-sticky-module-ng),确认与当前 Nginx 版本兼容(1.20–1.24 均支持),执行
./configure --add-module=/path/to/module [原有参数],再make && make install - 配置示例:
upstream backend { sticky cookie srv_id expires=1h domain=.example.com path=/ httponly secure; server 192.168.1.10:8080; server 192.168.1.11:8080; } - srv_id 是模块自动生成的 Cookie 名,值为内部哈希标识;expires 控制有效期,过期后重新分配;domain 和 path 必须与业务域名一致,否则浏览器不携带;httponly secure 防止 XSS 窃取、强制 HTTPS 下传输
备选方案:hash + $cookie_jsessionid(免编译)
若无法重新编译 Nginx,可利用内置 hash 指令,依赖后端已生成的业务 Cookie(如 Java 应用返回的 JSESSIONID)实现软粘性。
- 配置示例:
upstream backend { hash $cookie_jsessionid consistent; server 192.168.1.10:8080; server 192.168.1.11:8080; } - 前提:后端必须已正常设置
Set-Cookie: JSESSIONID=xxx,且客户端允许并持续携带该 Cookie - consistent 启用一致性哈希,当增减后端节点时,尽量减少已有用户路由变更
验证与注意事项
是否生效,可通过三步快速验证:
- 首次访问后,检查响应头是否有
Set-Cookie: srv_id=...或Set-Cookie: JSESSIONID=... - 多次刷新页面,抓包确认请求头中 Cookie 值稳定不变
- 对比后端日志,确认同一用户 IP 的多次请求只命中一台服务器
- 注意:浏览器禁用 Cookie 时,该机制退化为轮询;route 值若为明文(如 a/b),建议启用哈希混淆增强隐蔽性;某台后端宕机后,已有 Cookie 用户仍会尝试转发,需配合健康检查自动剔除故障节点











