当前位置: 首页 > news >正文

了解分布式Session

大家好,我这名CRUD工程师又来了,最近我的一个同事突然在看分布式Seesion的问题,然后我们两个也是互相讨论了一下,今天我就想着把分布式Session的知识点好好的梳理一下。

在很多系统中,用户的登录功能都是用Session去实现的,客户端填写好用户名和密码,发送一个请求,服务器收到请求之后,创建Session,然后返回当前Session对应的一个JessionId,浏览器存储在cookie中,当客户端调用其他方法给服务器发送请求的时候就会携带JessionId,服务端收到请求后,验证Session是否存在进而判断用户是否登录。

在分布式环境下,Session就会出现问题了,假如服务端部署在两个服务器A和B上

用户登录时,请求落在了服务器A上,服务器A创建了一个Session,并返回JessionId

用户获取个人信息时,请求落在了服务器B上,请求携带的JesssionId在服务器B上并不会找到对应的Session

这时候服务器B就会给客户端返回一个异常提醒(用户未登录),客户端收到返回值,用户就会发现自己又被T到登录界面了

接下来,我们就看看在分布式环境下如何实现Session的一致性

一 、客户端存储

既然分布式环境中,一个客户端的多个请求可能会落在多个服务器上,那么我们是否可以改变策略,直接将Session信息存储在客户端?
答案当然是可以的,服务器将Session信息直接存储到cookie中,这样就保证了Session的一致性,但是我们并不推荐这样去做,这样就会产生数据安全的隐患,因为将一些信息存储在cookie中,相当于就把这些信息暴露给了客户端,存在严重的安全隐患。

缺点

  • 系统安全性存在问题
  • cookie对于数据类型及数据大小有所限制

二 、Session复制

将服务器A的Session,复制到服务器B,同样将服务器B的Session也复制到服务器A,这样两台服务器的Session就一致了。像tomcat等web容器都支持Session复制的功能,在同一个局域网内,一台服务器的Session会广播给其他服务器。
在这里插入图片描述

缺点

  • 同一个网段内服务器太多,每个服务器都会去复制session,会造成服务器内存浪费。

三、Session黏性

利用Nginx服务器的反向代理,将服务器A和服务器B进行代理,然后采用ip_hash的负载策略,将客户端和服务器进行绑定,也就是说客户端A第一次访问的是服务器B,那么第二次访问也必然是服务器B,这样就不存在Session不一致的问题了。

在这里插入图片描述
缺点

  • 如果服务器A宕机了,那么客户端A和客户端B的Session就会出现丢失,并且客户端A、B的所有请求都会失败

四、session集中管理

这种方式就是将所有服务器的Session进行统一管理,可以使用redis等高性能服务器来集中管理Session,而且spring官方提供的spirng-session就是这样处理Session的一致性问题。这也是目前很多企业开发用到的比较多的一种分布式Session解决方案。

在这里插入图片描述

spring-session实战

Spring提供了处理分布式Session的解决方案——Spring SessionSpring Session提供了用于管理用户会话的API和实现。

Spring Session提供了对redismongodbmysql等常用的存储库的支持,Spring Session提供与HttpSession的透明整合,这意味着开发人员可以使用Spring Session支持的实现切换HttpSession实现。

我在网上找了一个Spring Session 实现的流程图
在这里插入图片描述
Spring Session添加了一个SessionRepositoryFilter的过滤器,用来修改包装请求和响应,包装后的请求为SessionRepositoryRequestWrapper,调用getSession()方法的时候实际上就是调用Spring Session实现了的Session

Spring Session使用非常简单,添加了相关依赖后,直接操作HttpSession就可以实现效果。

pom.xml

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId></dependency>

yml

spring:session:# session 失效时间(分钟)timeout: 86400# session 使用redis存储  store-type: redis# redis 配置redis:# redis 端口号port: 6379# redis 服务器地址host: localhost# redis库database: 0# redis 密码password: 123456

使用session

public String test( HttpServletRequest request){HttpSession session = request.getSession();session.setAttribute("key_big_handsome","value:it is me");return session.getAttribute("key_big_handsome").toString();
}

执行了这个方法,我们看redis
在这里插入图片描述

  • 第一个用来表示Session在Redis中的过期,这个k-v不存储任何有用数据,只是表示Session过期而设置。这个key在Redis中的过期时间即为Session的过期时间间隔。
  • 第二个存储这个Session的id,是一个Set类型的Redis数据结构。这个key中的最后的1681633260000值是一个时间戳,根据这个Session过期时刻滚动至下一分钟而计算得出。
  • 第三个用来存储Session的详细信息,包括Session的过期时间间隔、最近的访问时间、attributes等等。

Spring Session中有个定时任务,每个整分钟都会查询相应的spring:session:expirations:整分钟的时间戳中的过期SessionId,然后再访问一次这个SessionId,即spring:session:sessions:expires:SessionId,以便能够让Redis及时的产生key过期事件——即Session过期事件。

http://www.lryc.cn/news/59765.html

相关文章:

  • 仿真创新大赛—国三省一 智能鱼缸(proteus)(stm32)
  • 【ARMv8 编程】A64 数据处理指令——位域字节操作指令
  • ctfshow 愚人杯菜狗杯部分题目(flasksession伪造ssti)
  • linux拓展笔记——【补充学习知识点】
  • 为何银行各岗位之间的薪酬差别如此之大?
  • TensorFlow 深度学习第二版:1~5
  • 微前端micro-app的使用
  • 【JUC】Java内存模型之JMM
  • Win11快速打开便签和使用技巧分享
  • CSS:横向导航栏
  • 视频动态库测试及心得
  • 陶泓达:4.18午间欧盘黄金原油最新精准操作建议!
  • 环境变量相关知识
  • 如何快速入门ChatGPT
  • Akka定时任务schedule()方法
  • Python实现处理和分析大规模文本数据集,包括数据清洗、标注和预处理
  • 灌区量测水系统
  • 3.3 泰勒公式
  • ubuntu中通过vscode编译调试ORB-SLAM3
  • 阿里版 ChatGPT 突然上线!
  • 《Kubernetes部署篇:Ubuntu20.04基于containerd部署kubernetes1.24.12单master集群》
  • MAZDA CX-50没现车怎么办?赶紧去VR看车啊!
  • 结构体全解,适合初学者的一条龙深度讲解(附手绘图详解)
  • 什么是SD-WAN技术?企业网络优化的利器!
  • JAVA练习106- 生命游戏
  • 【案例教程】基于R语言、MaxEnt模型融合技术的物种分布模拟、参数优化方法、结果分析制图与论文写作实践技术
  • php7类型约束,严格模式
  • 2023-04-11 无向图的匹配问题
  • 国家出手管人工智能AI了
  • day24—选择题