校招必问: Redis 解决集群 Session 共享问题
📌 前言:从“以为做好了”到“被现实打脸”
相信很痛同学在做高并发项目之前,一直以为登录功能是最简单的。
只要 request.getSession()一下,用户就能登录了,对吧?
直到我把项目部署到 Nginx 集群 之后。
测试的时候差点把我送走:明明刚登录成功,刷新一下页面,又被踢回登录页了。
这就是我踩的第一个分布式大坑:Session 共享问题。
🚨 问题现象(集群下的灵异事件)
在单机模式下,一切岁月静好:
浏览器 → 服务器 A
Session 存在 A 的内存里 ✅
但是上了集群模式(多台服务器)后:
Nginx
/ \
Server A Server B
诡异的现象出现的原因:
-
用户第一次访问,请求被分配到 Server A,登录成功,Session 存在 A 里。
-
用户刷新页面,请求被分配到 Server B。
-
Server B 懵了 :我这儿没你的 Session 啊?
-
结果 :用户看到 “请重新登录”。
-
总结 : “这就是 Session 拷贝在集群下的致命缺陷:Session 是本地内存的,节点之间不共享,用户一换机器,登录态就丢了。”
📌 你必须懂的:Session 底层逻辑
很多同学只知道 request.getSession(),但不知道里面发生了什么。
1. Session 的创建流程
-
首次请求:服务端发现请求头里 没有
JSESSIONID。 -
创建对象:Tomcat 在内存中创建一个新的
HttpSession对象。 -
返回 ID:服务端通过响应头
Set-Cookie: JSESSIONID=xxx,把 ID 写给浏览器。
2. Session 的生命周期(面试常问)
|
阶段 |
触发条件 |
备注 |
|---|---|---|
|
创建 |
第一次调用 |
不一定是登录那一刻 |
|
存活 |
会话未中断 |
依赖 Cookie |
|
销毁 |
超时(默认30min) |
|
|
销毁 |
主动 |
退出登录时 |
|
销毁 |
服务器宕机 |
非持久化下致命 |
3,Session 的工作原理(核心流程)
1️⃣ 第一次请求
-
服务端发现请求中没有
SessionId -
创建一个新的 Session
-
生成一个唯一的
SessionId
2️⃣ 服务器返回 SessionId
-
通常通过 Cookie 返回给客户端
3️⃣ 后续请求
-
浏览器自动携带
SessionId -
服务端根据
SessionId查找对应的 Session
四、Redis 改进方案
Session 的本质没有改变,只是存储介质换了地方。
改造前(出问题)
用户 → Server A(Session 在 A 内存)
用户 → Server B(没有 Session) ❌
改造后(解决问题)
用户 → Server A / Server B
↓
Redis
工作流程
-
用户第一次访问 Server A
-
创建 Session
-
Session 数据写入 Redis
-
-
用户第二次访问 Server B
-
Server B 从 Redis 读取 Session
-
✅ 登录状态仍然有效
-
五、关键优化点
1️⃣ 设置有效期
-
防止 Redis 内存无限增长
-
与 Session 超时时间保持一致
2️⃣ 双拦截器设计(重点)
|
拦截器 |
作用 |
|---|---|
|
第一层 |
判断用户是否登录 |
|
第二层 |
刷新 Redis 中 Token / Session 的有效期 |
✅ 解决“用户一直在操作,却被强制下线”的问题。
💡 一句话总结(面试必背)
Session 的本质没有改变,只是将其存储实现从服务器内存替换为 Redis,从而解决分布式环境下的 Session 共享问题。
更多推荐




所有评论(0)