Nginx 开源版本身不支持原生的 Cookie 会话保持指令,该功能属于 Nginx Plus 商业特性或在开源版中需编译第三方模块;对于大多数开源版用户,建议优先评估 ip_hash 或应用层会话共享方案。
先说结论:若必须基于 Cookie 保持会话且使用开源版,需引入第三方模块否则只能退而求其次使用 ip_hash;若使用 Nginx Plus 则可直接配置 sticky 指令。
- 适合:后端服务无共享会话存储且需保持用户粘滞的场景
- 先准备:确认 Nginx 版本是开源版还是 Plus 版,以及是否允许引入第三方模块
- 验收:通过多次请求验证同一 Cookie 是否始终指向同一台后端服务器
命令速用版
# Nginx 开源版 (原生仅支持 ip_hash)\nupstream backend {\n ip_hash;\n server 192.168.1.10;\n server 192.168.1.11;\n}\n\n# Nginx Plus (支持 sticky cookie)\nupstream backend {\n sticky cookie srv_id expires=1h domain=.example.com path=/;\n server 192.168.1.10;\n server 192.168.1.11;\n}\n\n# 开源版 + 第三方模块 (推荐 nginx-sticky-module-ng,语法可能因版本而异)\nupstream backend {\n sticky name=route_id expires=1h path=/;\n server 192.168.1.10;\n server 192.168.1.11;\n}开源版编译第三方模块实操
若确定使用开源版且必须实现 Cookie 会话保持,需重新编译 Nginx 并注入第三方模块。以下是基于 commonly used fork nginx-sticky-module-ng 的实操步骤:
1. 获取源码
下载 Nginx 源码(版本需与当前运行版本一致或兼容)及第三方模块源码。
# 示例:获取第三方模块 (社区维护版本,地址可能变动)\ngit clone https://github.com/aizawa/nginx-sticky-module-ng.git\n\n# 下载对应版本的 Nginx 源码\nwget http://nginx.org/download/nginx-1.24.0.tar.gz\ntar -zxvf nginx-1.24.0.tar.gz\ncd nginx-1.24.02. 配置编译参数
使用 ./configure 命令,关键是指定 `--add-module` 路径。注意保留原有编译参数,可通过 nginx -V 查看。
# 查看原有编译参数\nnginx -V\n\n# 添加第三方模块重新配置 (示例)\n./configure \\\n `--prefix`=/etc/nginx \\\n `--sbin-path`=/usr/sbin/nginx \\\n `--add-module`=/path/to/nginx-sticky-module-ng3. 编译与替换
编译生成二进制文件并替换原有 Nginx 程序,随后重载配置。
make\nsudo cp objs/nginx /usr/sbin/nginx/\nsudo nginx -t\nsudo nginx -s reload如何验证模块是否生效
1. 检查编译模块列表
在执行编译前,可使用 nginx -V 查看当前是否已包含 sticky 相关模块。若输出中无相关模块信息,则原生不支持 sticky 指令。
nginx -V 2>&1 | grep -i sticky2. 检查响应头
使用 curl -v http://your-domain.com 发起请求,观察响应头中是否包含 Set-Cookie 字段,且字段名与配置一致(如 srv_id 或 route_id)。
3. 携带 Cookie 多次请求
使用 curl -b "route_id=xxx" http://your-domain.com 多次发起请求,同时查看后端服务器的访问日志。若配置生效,所有携带相同 Cookie 的请求日志应出现在同一台后端服务器的日志文件中。
4. 后端日志确认
在后端应用中打印服务器主机名或 IP。连续刷新页面,若会话保持生效,页面显示的服务器标识不应发生变化。
常见坑
1. 开源版误用指令
很多教程直接给出 sticky 配置但未说明需第三方模块,导致开源版用户配置重载失败。务必先 nginx -t,若报错 unknown directive "sticky" 即表示未编译该模块。
2. 第三方模块语法差异
不同 fork 版本的第三方 sticky 模块指令参数可能不同(如 name= 还是 cookie=),编译前请查阅对应模块的 README 说明,不要直接复制配置。
3. ip_hash 的局限性
若使用开源版原生的 ip_hash,当客户端网络切换导致 IP 变化时,会话会中断。且 NAT 环境下多个用户可能共享同一出口 IP,导致负载不均。
4. 升级断裂风险
第三方模块非官方维护,升级 Nginx 版本时可能需重新编译,存在兼容性风险。生产环境引入前需在测试环境充分验证,并锁定 Nginx 版本避免意外升级。
5. Cookie 属性配置
若站点启用 HTTPS,建议在 Cookie 配置中开启 secure 属性,防止 Cookie 通过明文传输。同时注意 domain 和 path 的设置,避免浏览器拒绝写入。
参考来源
- Nginx 官方文档 - ngx_http_upstream_module (ip_hash 指令说明)
- Nginx Plus 管理员指南 - NGINX Load Balancer (sticky 指令说明)
- GitHub - nginx-sticky-module-ng (第三方模块源码参考)