nginx实现基于cookie的会话保持需优先选用nginx-sticky-module-ng模块,通过自动注入srv_id cookie确保同一用户路由至固定后端;若无法编译,则用hash $cookie_jsessionid consistent实现软粘性,依赖后端已生成的jsessionid。

要让 Nginx 实现基于 Cookie 的会话保持,核心是让同一个用户的后续请求始终被转发到同一台后端服务器。这在 Session 存储于本地内存(如 Tomcat 默认 HttpSession)时尤为关键——否则用户可能反复登录、购物车丢失。
为什么不用 ip_hash?
ip_hash 看似简单,但实际限制明显:
- 企业或校园出口常为 NAT,大量用户共用一个公网 IP,全部压到一台后端,造成严重倾斜;
- 移动网络切换(4G→WiFi)、动态 IP 变更会导致会话中断;
- CDN 或代理层会掩盖真实客户端 IP,使 ip_hash 失效。
使用第三方 sticky 模块(推荐方案)
开源社区广泛采用 nginx-sticky-module-ng(原 nginx-sticky-module 的活跃分支),它无需修改业务代码,自动注入和识别 route cookie。
配置示例:
upstream backend {
sticky cookie srv_id expires=1h domain=.example.com path=/;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
说明:
- srv_id 是生成的 cookie 名,值为内部计算的唯一路由标识;
- expires=1h 控制 cookie 有效期,过期后重新分配;
- domain 和 path 需与业务域名匹配,确保前端能正确携带;
- 模块会在首次响应中自动 set-cookie,后续请求自动识别并路由。
使用 hash + $cookie_xxx(免编译方案)
若无法编译安装模块,可用 Nginx 内置 hash 指令结合已有的业务 Cookie(如 jsessionid)实现软粘性:
upstream backend {
hash $cookie_jsessionid consistent;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
前提条件:
- 后端 Java 应用已正常返回
Set-Cookie: JSESSIONID=xxx; - 确保客户端浏览器允许并携带该 Cookie;
- consistent 参数启用一致性哈希,节点增减时尽量保留原有映射关系。
验证是否生效
最直接的方式是观察后端服务日志或响应头:
- 访问一次后,检查响应头是否包含
Set-Cookie: srv_id=...(sticky 模块)或Set-Cookie: JSESSIONID=...(hash 方案); - 多次刷新页面,抓包查看请求头中的 Cookie 是否稳定不变;
- 对比两台后端服务器的访问日志,确认同一用户 IP 在多次请求中只命中一台。
注意:Cookie 会话保持依赖浏览器支持 Cookie。若需兼容无 Cookie 环境(如部分爬虫或老旧终端),应配合 fallback 策略,例如降级为 ip_hash 或引导至统一登录页。











