Nginx官方不支持基于Cookie的会话保持,需通过第三方模块nginx-sticky-module-ng实现:先编译安装该模块,再在upstream中配置sticky cookie JSESSIONID expires=1h domain=.example.com path=/ httponly secure,并确保Tomcat正确设置sessionCookiePath与sessionCookieDomain以匹配。

Nginx 本身不内置 sticky 模块,官方版本的 upstream 不支持基于 Cookie 的会话保持(session stickiness)。要实现 Tomcat 多节点下的会话粘性,需借助第三方模块(如 nginx-sticky-module-ng)或改用 Nginx Plus / OpenResty / 或原生支持的现代替代方案。下面以最常用、轻量且兼容主流 Nginx 版本的 nginx-sticky-module-ng 为例,说明如何配置基于 Cookie 的会话保持。
确认环境与准备 sticky 模块
该模块非官方维护,需手动编译进 Nginx。注意:Nginx 1.19+ 对模块 ABI 有调整,建议使用匹配的分支(如 nginx-sticky-module-ng 的 master 或 nginx-1.18 分支)。
- 下载并解压对应 Nginx 源码(版本需与当前运行版一致,如 1.20.2)
- 克隆 sticky 模块源码:
git clone https://www.php.cn/link/b050285d2ce40b4398647c923ffc769f.git - 重新编译 Nginx:
./configure --add-module=/path/to/nginx-sticky-module-ng [其他原有参数] && make && sudo make install - 验证是否加载成功:
nginx -V 2>&1 | grep -o sticky应输出模块信息
配置 upstream 启用 sticky cookie
在 http 块中定义带 sticky 的 upstream,指定 cookie 名、过期时间、加密密钥(可选)及后端 Tomcat 节点:
upstream backend_tomcat {
sticky cookie JSESSIONID expires=1h domain=.example.com path=/ httponly secure;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
-
JSESSIONID是 Tomcat 默认会话 ID 名,必须与应用实际使用的 cookie 名一致 -
expires=1h控制客户端 cookie 过期时长,建议略长于 Tomcat 的maxInactiveInterval -
domain和path需与应用部署路径对齐(如应用在/app,则设path=/app) -
httponly secure提升安全性(后者仅限 HTTPS 环境启用)
确保 Tomcat 正确生成和识别会话 Cookie
Tomcat 需配合返回带 Path、Domain 的 JSESSIONID,否则 sticky 模块可能无法捕获或更新 cookie:
- 在
conf/context.xml中添加:<Context sessionCookiePath="/" sessionCookieDomain=".example.com" /> - 若使用 Spring Boot,可在
application.properties中配置:server.servlet.session.cookie.path=/、server.servlet.session.cookie.domain=.example.com - 禁用 URL 重写(避免 fallback 到
;jsessionid=xxx):sessionCookieHttpOnly=true+sessionCookieSecure=true(HTTPS 下)
验证 sticky 行为与故障排查
部署后通过 curl 或浏览器开发者工具检查请求/响应头中的 Set-Cookie 和 Cookie 字段:
- 首次请求应收到
Set-Cookie: JSESSIONID=abc123...; Path=/; Domain=.example.com; HttpOnly; Secure - 后续请求需携带该 cookie,且 Nginx 日志中
$upstream_addr应始终指向同一台 Tomcat IP - 常见问题:
400 Bad Request(cookie 域不匹配)、sticky 不生效(Tomcat 返回的 cookie path 与 upstream 中设置不一致)、cookie 被覆盖(多个 upstream 共享同名 cookie) - 调试技巧:临时开启
error_log /var/log/nginx/sticky.log debug;,查看 sticky 模块日志(需编译时加--with-debug)


















