spring-session+redis解决共享session问题

在集群中,由于有多台服务器,但是session却应该还是一个,session 如何共享就需要被解决;

现在有多种方式来解决session共享问题:

1、通过nginx,根据访问者ip来做hash,从而在每次访问时都是固定的一台服务器,那个session 对象也就是固定的一个了

2、用token来代替session

3、用spring-session+redis实现session共享

spring-session+redis实现session共享的原理其实很简单,就是把session对象存到redis中,每台服务器被访问时,通过sessionid到redis中拿到session对象;

具体的实现方式是:实现了一个过滤器filter,在所有访问请求进入servlet前将其拦截,在filter中,对request对象和response对象做了一层包装,然后放行,执行后面的逻辑,后面如果要用session对象时,调用getsession()方法,其实调用的就是包装后的request对象的getsession()方法,这个方法中,就是从redis里获取session了,所有的服务器都从redis中获取同一个session,那么共享session就实现了;当然,还有一些点也需要注意一下,就是redis在创建保存某个session时,其实创建了三个相关key,了解redis的key删除策略的应该明白,redis不是实时删除到期key的这三个key的数据结构分别是:

A) "spring:session:sessions:39feb101-87d4-42c7-ab53-ac6fe0d91925"

B) "spring:session:expirations:1523934840000"

C) "spring:session:sessions:expires:39feb101-87d4-42c7-ab53-ac6fe0d91925"

他们公用的前缀是 spring:session A 类型键的组成是前缀 +”sessions”+sessionId,对应的值是一个 hash 数据结构。 { "lastAccessedTime": 1523933008926,/2018/4/17 10:43:28/ "creationTime": 1523933008926, /2018/4/17 10:43:28/ "maxInactiveInterval": 1800, "sessionAttr:name": "xu" } 其中 creationTime(创建时间),lastAccessedTime(最后访问时间),maxInactiveInterval(session 失效的间隔时长) 等字段是系统字段,sessionAttr:xx 是HttpServletRequest.setAttribute("xxx","xxx")存入的,它可能会存在多个键值对,用户存放在 session 中的数据如数存放于此。A 类型键对应的默认 TTL 是 30+5 分钟。(30是默认有效时间,可以设置的)

B 类型键的组成是前缀 +”expirations”+ 时间戳。其对应的值是一个 set 数据结构,这个 set 数据结构中存储着一系列的 C 类型键。B 类型键对应的默认 TTL 是 30+5 分钟 [ "expires:39feb101-87d4-42c7-ab53-ac6fe0d91925" "expires:836d11aa-11e2-44e0-a0b2-92b54dec2324" ] C 类型键的组成是前缀 +”sessions:expires”+sessionId,对应一个空值,它仅仅是 sessionId 在 redis 中的一个引用,C 类型键对应的默认 TTL 是 30 分钟。

这里注意一个细节,spring-session 中 A 类型键的过期时间是 35 分钟,比实际的 30 分钟多了 5 分钟,这意味着即便 session 已经过期,我们还是可以在 redis 中有 5 分钟间隔来操作过期的 session。于此同时,spring-session 引入了 C 类型键来作为 session 的引用。

为什么引入 C 类型键?redis只会告诉我们哪个键过期了,不会告诉我们内容是什么。关键就在于如果 session 过期后监听器可能想要访问 session 的具体内容,然而自身都过期了,还怎么获取内容 。所以,C 类型键存在的意义便是解耦 session 的存储和 session 的过期,并且使得 server 获取到过期通知后可以访问到 session 真实的值。对于用户来说,C 类型键过期后,意味着登录失效,而对于服务端而言,真正的过期其实是 A 类型键过期,这中间会有 5 分钟的误差。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值