Nginx 实现会话保持(Session Persistence)

Nginx 实现会话保持(Session Persistence)主要有 3 种方式 ,生产环境最常用的是 sticky cookieip_hash,而 sticky learn 是更灵活的高级方案。


一、三种方式对比(先看结论)

方式 原理 优点 缺点 生产推荐度
ip_hash 按客户端 IP 哈希分配 简单,无需配置 代理 IP 会失真,后端宕机会丢会话 ⭐⭐ 简单场景
sticky cookie Nginx 插入 cookie,客户端携带 精准,不受 IP 影响 需要浏览器支持 cookie ⭐⭐⭐⭐⭐ 首选
sticky learn 动态学习请求与后端映射 兼容性好,不修改响应 内存消耗,仅 Nginx Plus 或第三方模块 ⭐⭐⭐⭐ 大并发场景

二、方式一:ip_hash(最简单)

配置示例

nginx 复制代码
upstream tomcat_cluster {
    ip_hash;   # 开启 IP 哈希会话保持
    
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
}

工作原理

  1. Nginx 对客户端 IP 地址计算哈希值
  2. 同一 IP 的请求始终落在同一台后端服务器上

适用场景

  • 客户端 IP 相对固定(如企业内网)
  • 对会话保持要求不苛刻的场景

典型问题

  • 用户通过公司统一出口上网 → 所有用户看起来像一个 IP → 全部落到同一台服务器上
  • 后端服务器宕机 → 该服务器上的会话全部丢失

三、方式二:sticky cookie(生产首选,需要编译第三方模块)

Nginx 官方开源版原生不支持,需要编译 nginx-sticky-module-ng 模块

Nginx Plus 商业版原生支持

配置示例

nginx 复制代码
upstream tomcat_cluster {
    sticky cookie srv_id expires=1h domain=.example.com path=/;
    
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
}

参数说明

参数 说明
cookie srv_id 设置 cookie 名称(可自定义)
expires=1h cookie 有效期 1 小时
domain=.example.com cookie 生效的域名
path=/ cookie 生效的路径

工作原理(关键)

Tomcat2 Tomcat1 Nginx 用户 Tomcat2 Tomcat1 Nginx 用户 1. 首次请求(无 cookie) 2. 选择一台后端(如 tomcat1) 3. 响应内容 4. 响应 + Set-Cookie: srv_id=tomcat1 5. 后续请求(携带 cookie) 6. 根据 cookie 直接发往 tomcat1

优势

  • 精准:不受代理 IP 影响
  • 透明:后端 Tomcat 无需任何改造
  • 兼容性好 :支持 sticky + fallback 做高可用

四、方式三:sticky learn(Nginx Plus 或 OpenResty)

配置示例(Nginx Plus)

nginx 复制代码
upstream tomcat_cluster {
    zone upstream_zone 64k;
    sticky learn
        create=$upstream_cookie_sessionid
        lookup=$cookie_sessionid
        zone=client_sessions:1m;
    
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
}
对比维度 sticky cookie sticky learn
谁插入 cookie Nginx 插入新 cookie 不插入 cookie,学习应用已有的 cookie
后端应用要求 无要求 应用需要自己生成一个 sessionid cookie
升级兼容性 已有 cookie 可能变化 无感知,应用自己的 cookie 不变
典型使用场景 新项目,无历史包袱 老项目改造、不想改现有 cookie 逻辑

五、三种方式选型决策树



可容忍
不可容忍


需要会话保持
客户端 IP 是否相对固定?
会话丢失容忍度?
使用 sticky cookie
ip_hash
不想改造后端应用?
sticky cookie 或 ip_hash
sticky learn

学习应用已有 cookie


六、生产环境最佳实践

nginx 复制代码
upstream tomcat_cluster {
    sticky cookie srv_id expires=1h;
    
    server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
}

为什么还要做共享存储?

即使 Nginx 做了会话保持,如果后端 Tomcat 宕机,用户会话还是会丢失。

所以 真正的生产高可用 = Nginx 会话保持 + Redis 共享存储

  • Nginx 保证同一用户的请求尽量发到同一台服务器(性能好、减少跨节点读取 session)
  • Redis 保证即使那台服务器宕机,其他服务器也能从 Redis 中读取 session

七、排查建议

如果配置了会话保持但还是不生效:

现象 可能原因 排查方法
请求总是落到不同服务器 cookie 未携带 打开浏览器开发者工具 → Application → Cookies,检查 cookie 是否存在
ip_hash 不生效 多级代理(X-Forwarded-For) 使用 real_ip_header 获取真实 IP
负载严重不均 ip_hash 算法分布不均 考虑改用 sticky cookie

八、一句话总结

Nginx 实现会话保持最常用的方式是通过 sticky cookie 给客户端打标记,让后续请求始终落到同一台后端服务器上。

但别忘了:Nginx 会话保持 + Redis 共享存储 = 真正的生产高可用

相关推荐
Y38153266222 分钟前
Docker Compose 服务依赖与健康检查:healthcheck 让容器按正确顺序启动
运维·docker·容器
稳联技术老娜32 分钟前
伺服内嵌EtherNet IP方案:嵌入式小板SPI通讯固件Demo程序适配改造
运维·服务器·网络
Rain的Java大神之路1 小时前
JavaWeb开发如何解决跨域问题
java·前端·后端·nginx·web安全·面试·运维开发
en.en..1 小时前
Linux系统编程:fcntl 与 ioctl
linux·运维·服务器
荣合技术服务2 小时前
Codex 实战:用 AI 写运维脚本
运维·codex
李昊哲小课2 小时前
Deepin 25 上安装 Docker CE 实战记录
运维·docker·容器·deepin
pingglala2 小时前
ubuntu-nat模式不能上网解决方法
linux·运维·ubuntu
一技安身3 小时前
【信创】外网aarch64终端安装deepseek Ragflow 迁移至内网银河麒麟服务器
运维·服务器
考虑考虑4 小时前
ElasticSearch索引命令
运维·后端·elasticsearch
和裕5 小时前
光伏储能定制加强型瓦楞纸箱:降低组件运输隐裂率与售后损耗的核心价值
大数据·运维·网络·人工智能·算法