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 共享存储 = 真正的生产高可用

相关推荐
Yana.nice18 小时前
nginx的四种代理模式
运维·nginx·代理模式
fastjson_18 小时前
win11 关闭VBS
运维
夹芯饼干18 小时前
Linux第十三周配置网络
linux·运维·服务器
会Tk矩阵群控的小木18 小时前
2026最新iOS免越狱手机群控方案对比与技术难点实战解析
运维·macos·objective-c·cocoa·个人开发
ITyunwei098718 小时前
能否在客户投诉前发现并解决问题?
运维
千百元19 小时前
Linux 远程传输实战指南
运维·服务器
Cat_Rocky19 小时前
k8s prometheus监控平台-alertmanager告警
运维·kubernetes·prometheus
Harm灬小海19 小时前
【云计算学习之路】企业常用服务搭建:MySQL 8.0
linux·运维·学习·mysql·云计算
杨云龙UP19 小时前
Oracle Flashback Query 实战练习:误更新、误删除数据如何快速找回?
linux·运维·数据库·sql·oracle·flashback