ToB企服应用市场:ToB评测及商务社交产业平台
标题:
基于Redis 的分布式 session 图解
[打印本页]
作者:
圆咕噜咕噜
时间:
3 天前
标题:
基于Redis 的分布式 session 图解
Redis 分布式 Session 工作原理
1. 传统 Session 的题目
在传统单服务器环境中,HTTP Session 存储在应用服务器的内存中。这在分布式体系中会导致题目:
用户的请求可能被分发到不同服务器,导致会话不一致
服务器宕机会导致会话丢失
需要依赖负载平衡器的会话粘性(sticky session)机制,限定了体系的伸缩性
2. Spring Session + Redis 解决方案
当设置了Spring Session + Redis后,体系会:
拦截请求处理流程
:
Spring Session 利用一个过滤器(SpringSessionRepositoryFilter)拦截全部HTTP请求
这个过滤器由DelegatingFilterProxy代理,在Spring Boot应用中自动设置
更换原生Session实现
:
过滤器会将容器原生的HttpSession实现更换为Spring自界说的实现
全部对HttpSession的操作现实上都被Spring Session接管
Session数据外部化
:
全部会话数据存储在Redis中,而非应用服务器内存
客户端仍然通过Cookie接收会话ID
服务器利用该ID从Redis中检索完整的会话数据
3. Redis 存储格式
Redis中的几个关键数据结构:
Strings范例
:spring:session:sessions:expires:{sessionId} - 用于跟踪会话过期
Hash表范例
:spring:session:sessions:{sessionId} - 存储现实的会话数据
Sets范例
:spring:session:expirations:{timestamp} - 用于管剖析话的过期机制
4. 请求处理流程
请求到达
:
客户端发送请求,包含sessionID的Cookie
Spring Session过滤器拦截请求
会话检索
:
从Cookie中提取sessionID
利用该ID从Redis查询会话数据
创建包含该数据的会话对象
请求处理
:
应用程序利用该会话对象,仿佛它是标准的HttpSession
对会话的任何修改都被跟踪
请求完成
:
如果会话数据被修改,更新存储在Redis中的数据
如有必要,更新过期时间
5. 技术亮点
无侵入性
:应用代码不需要任何改变,正常利用HttpSession接口
无需会话粘性
:负载平衡器不再需要设置sticky session
弹性伸缩
:服务器可以随时添加或移除,不影响用户会话
容错性
:单个服务器故障不会导致用户会话丢失
集中管理
:会话数据集中存储,便于监控和管理
这种计划使得Spring应用可以在分布式环境中无缝扩展,同时保持用户会话的一连性和一致性,是微服务架构中解决用户状态管理的优雅方案。
客户端先 带着 HTTP 请求到 负载平衡器
负载平衡器 转发请求到应用服务器
被SpringSessionFiliter 拦截
从 Cookie 中提取 SessionID
如果 该sessionID 存在,通过 该sessionID 从 SessionRespository 获取会话, SessionRespository 查询 Redis 中的 会话数量,RedisOperations 给Redis 服务器发送了 GET spring:session:sessions:{sessionId}。Redis 给 RedisOperations 返回数据。最终在 SessionRespository 构建请求对象给 SpringSessionFiliter。
如果 该sessionID 不存在大概过期,那么 SpringSessionFiliter 给 SessionRepository 创建新的会话。sessionRepository 在 Redis 中创建新会话,
Strings范例:spring:session:sessions:expires:{sessionId} - 用于跟踪会话过期
Hash表范例:spring:session:sessions:{sessionId} - 存储现实的会话数据
Sets范例:spring:session:expirations:{timestamp} - 用于管剖析话的过期机制
创建完成后,返回 新的session 对象给 SpringSessionFiliter 。
业务处理中可能发生修改 会话数量,如果有 SpringSessionFiliter 调用 SessionRepository 保存会话的变更,更新Redis 中的会话数量, HMSET 更新 会话数量,重置过期时间。
Mermind 画图代码:
sequenceDiagram
participant C as 客户端
participant LB as 负载均衡器
participant F as SpringSessionFilter
participant S as SessionRepository
participant R as RedisOperations
participant RD as Redis服务器
C->>LB: 1. HTTP请求(带SessionID Cookie)
LB->>F: 2. 转发请求到应用服务器
F->>F: 3. 拦截请求
F->>F: 4. 从Cookie中提取SessionID
alt 存在SessionID
F->>S: 5a. 通过SessionID获取会话
S->>R: 6a. 查询Redis中的会话数据
R->>RD: 7a. GET spring:session:sessions:{sessionId}
RD-->>R: 8a. 返回会话数据
R-->>S: 9a. 返回会话数据
S-->>F: 10a. 构建Session对象
else 不存在SessionID或会话已过期
F->>S: 5b. 创建新会话
S->>R: 6b. 在Redis中创建新会话
R->>RD: 7b. HMSET spring:session:sessions:{newId}
R->>RD: 8b. SET spring:session:sessions:expires:{newId}
R->>RD: 9b. SADD spring:session:expirations:{expireTime}
RD-->>R: 10b. 确认创建成功
R-->>S: 11b. 返回新会话ID
S-->>F: 12b. 返回新Session对象
end
F->>+S: 13. 包装为SessionRepositoryRequestWrapper
S->>-F: 14. 返回包装后的请求对象
F->>F: 15. 继续请求处理链
Note over F,S: 业务逻辑处理期间可能会修改会话数据
F->>S: 16. 保存会话变更(如有)
S->>R: 17. 更新Redis中的会话数据
R->>RD: 18. HMSET 更新会话数据
R->>RD: 19. 重置过期时间
F->>LB: 20. 返回HTTP响应
LB->>C: 21. 转发响应
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4