Nginx 实现会话保持(Session Persistence)

Nginx 实现会话保持(Session Persistence)主要有 3 种方式 ,生产环境最常用的是 sticky cookie 和 ip_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 共享存储 = 真正的生产高可用。

相关推荐
kkkkkkkkkk_Z6 分钟前
新手自学嵌入式 | 学习日记: Linux驱动进阶 —— Platform总线与I2C子系统实战
linux·运维·学习
Android系统攻城狮8 分钟前
Linux Gstreamer深度解析之gst_audio_aggregator_set_sink_caps调用流程与实战(九十一)
linux·运维·服务器·gstreamer音视频·音视频进阶
John_Hui39 分钟前
CentOS7安装Nginx
linux·服务器·nginx
怪力左手40 分钟前
cuda-toolkit离线安装
linux·运维·人工智能
Gauss松鼠会40 分钟前
GaussDB 内存相关参数及故障诊断
运维·数据库·sql·oracle·性能优化·架构·gaussdb
无人生还别怕1 小时前
如何搭建k8s服务(docker部署)
linux·运维·docker·云原生·容器·kubernetes·openanolisos
AnTrust1 小时前
代码签名证书品牌价格对比:DigiCert、GlobalSign、Comodo、Certum怎么选
运维·服务器·ssl
程序员-Benothing1 小时前
Linux磁盘管理教程:MBR、GPT、fdisk、parted分区实战
linux·运维·服务器
小HANN2 小时前
(索引 + SQL 优化):《MySQL 底层探秘②:B + 树索引与 Explain 实战,根治线上慢 SQL》
linux·运维·服务器·经验分享
wtblszn2 小时前
活性炭吸附塔组态监控运维系统方案
运维