文章字数:721,阅读全文大约需要2分钟
三种redis中保存session的key
spring:session:sessions:sessionIdspring:session:expirations:时间戳spring:session:sessions:expires:sessionId
spring:session:是三个键公用的前缀
sessions
spring:session:sessions:sessionId的数据类型是hash类型,其中保存着session相关信息和session的数据。默认TTL是35分钟
1 | "lastAccessedTime": 1523933008926,/*2018/4/17 10:43:28*/ #最后访问时间 |
expirations:
redis的过期处理优先级很低,如果有很多过期的键就会出现键已经过期但是未删除- 确保
redis的键过期的方式有两个:访问过期的键、手动删除 - 基于以上两点,
spring会定时手动清除过期的键。spring:session:expirations:时间戳中保存的数据为set类型,其中保存着时间戳所在的一分钟之内过期的session,有数据访问就移除,添加到下一个时间段的set中。使用专门的键保存过期需要确保删除的session可以避免全局查找,然后一个个访问失效时间等信息。
用户快速操作可能会带来并发问题,在两个时间段都进行了请求。session的过期时间应该向后推两次,但是可能第一次向后推还没完成第二次就完成了(两次操作处于时间段节点)这样就造成session过期时间存在于两个时间段中。
此时如果直接删除会造成时间差,比预计删除早了一分钟。所以不能使用删除,使用hasKey命令访问过期的key,让redis自动删除。
sessions:expires
spring:session:sessions:expires:sessionId的值为空,sessions中保存着session的具体值,sessions:expires则是代表session的有效时间。spring需要在知道session过期后拿到过期session的详细信息并进行操作。然而redis的键空间通知keyspace notifications只会说明那个键过期了,无法访问过期的键。于是设置了sessions:expires代表session过期时间,这个键过期了代表session过期。存储信息的sessions键则多存活5分钟,以便过期后访问信息。spring中监听过期事件:
1 | # 配置 |