Spring boot集成Redis实现sessions共享时,sessions过期时间问题分析
2023-09-14 09:12:39 时间
Springboot鼓励零配置的方式,帮你做好大部分重复劳动的事,好到不能再好;具体的Redis安装方法和Springboot集成Redis方法,可以去搜索相关文章或参考该文章http://www.cnblogs.com/mengmeng89012/p/5519698.html。
当做用户权限管理时,一般都设置一个session过期时间,以确保用户长时间不操作时自动退出系统。
Spring seesions的原理可以参考该文章:http://blog.csdn.net/wojiaolinaaa/article/details/62424642
在springboot中设置該值的方法如下:
-
-
-
public class RedisSessionConfig {
-
-
}
即开启Redis共享sessions的配置类的注解设置maxInactiveIntervalInSeconds的值,单位为秒,默认值为1800秒;问题来了,当设置其为600秒时,在redis的客户端查看sessions的key的过期时间时(redis命令:ttl key,查看其有效时间),发现該值为1100秒;有问题有疑惑找源码,集成redis的代码在spring-sessions包中,找到
org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession注解,该注解的解析类为:
org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration;可以看到
maxInactiveIntervalInSeconds默认值为1800秒,找到setImportMetadata函数:
-
public void setImportMetadata(AnnotationMetadata importMetadata) {
-
-
Map<String, Object> enableAttrMap = importMetadata
-
.getAnnotationAttributes(EnableRedisHttpSession.class.getName());
-
AnnotationAttributes enableAttrs = AnnotationAttributes.fromMap(enableAttrMap);
-
/**
-
*解析注解,获取maxInactiveIntervalInSeconds赋值给配置类的maxInactiveIntervalInSeconds对象
-
*/
-
this.maxInactiveIntervalInSeconds = enableAttrs
-
.getNumber("maxInactiveIntervalInSeconds");
-
String redisNamespaceValue = enableAttrs.getString("redisNamespace");
-
/**
-
*设置命名空间
-
*/
-
if (StringUtils.hasText(redisNamespaceValue)) {
-
this.redisNamespace = this.embeddedValueResolver.resolveStringValue(redisNamespaceValue);
-
}
-
this.redisFlushMode = enableAttrs.getEnum("redisFlushMode");
-
}
利用Redis作为sessions共享仓实现类为org.springframework.session.data.redis.RedisOperationsSessionRepository
其执行session过期策略的实现类为RedisSessionExpirationPolicy,其过期的具体函数如下:
-
public void onExpirationUpdated(Long originalExpirationTimeInMilli,
-
ExpiringSession session) {
-
String keyToExpire = "expires:" + session.getId();
-
long toExpire = roundUpToNextMinute(expiresInMillis(session));
-
-
if (originalExpirationTimeInMilli != null) {
-
long originalRoundedUp = roundUpToNextMinute(originalExpirationTimeInMilli);
-
if (toExpire != originalRoundedUp) {
-
String expireKey = getExpirationKey(originalRoundedUp);
-
this.redis.boundSetOps(expireKey).remove(keyToExpire);
-
}
-
}
-
-
long sessionExpireInSeconds = session.getMaxInactiveIntervalInSeconds();
-
String sessionKey = getSessionKey(keyToExpire);
-
-
if (sessionExpireInSeconds < 0) {
-
this.redis.boundValueOps(sessionKey).append("");
-
this.redis.boundValueOps(sessionKey).persist();
-
this.redis.boundHashOps(getSessionKey(session.getId())).persist();
-
return;
-
}
-
-
String expireKey = getExpirationKey(toExpire);
-
BoundSetOperations<Object, Object> expireOperations = this.redis
-
.boundSetOps(expireKey);
-
expireOperations.add(keyToExpire);
-
/**
-
*关键在此处,在设置的基础上增加了5分钟
-
/
-
long fiveMinutesAfterExpires = sessionExpireInSeconds
-
+ TimeUnit.MINUTES.toSeconds(5);
-
-
expireOperations.expire(fiveMinutesAfterExpires, TimeUnit.SECONDS);
-
if (sessionExpireInSeconds == 0) {
-
this.redis.delete(sessionKey);
-
}
-
else {
-
this.redis.boundValueOps(sessionKey).append("");
-
this.redis.boundValueOps(sessionKey).expire(sessionExpireInSeconds,
-
TimeUnit.SECONDS);
-
}
-
this.redis.boundHashOps(getSessionKey(session.getId()))
-
.expire(fiveMinutesAfterExpires, TimeUnit.SECONDS);
-
}
-
相关文章
- Spring-boot_Spring Boot
- 基于Spring boot的外卖项目瑞吉外卖Day10使用Redis缓存技术
- 一文搞懂阿里云服务器部署Redis并整合Spring Boot
- Spring Boot 项目集成Redis的方式详解
- Spring boot+redis实现消息发布与订阅的代码
- Spring之Redis访问(Spring-data-redis)详解数据库
- Spring Boot(二十):使用spring-boot-admin对spring-boot服务进行监控详解编程语言
- Spring Boot(十四):spring boot整合shiro-登录认证和权限管理详解编程语言
- Spring Boot(三):Spring Boot中Redis的使用详解编程语言
- Spring框架下整合Redis的实现(spring整合redis)
- Redis:高效的内存数据库(redis内存数据库)
- Spring Boot 2.x :通过 spring-boot-starter-hbase 集成 HBase
- 限制使用 Redis 实现数量限制(redis数量)
- 精细化管理基于Redis的配置实践(若依redis配置)
- 续命拯救Redis锁(续命redis锁)
- 提升效率极致管理Redis缓存(管理redis缓存)
- redis确保登录唯一性的保障(登录唯一性redis)
- 易语言实现Redis读写一种新思路(易语言读写 redis)
- 春满活力Redis存储专业解决方案(spring.redis)
- 注入Spring精神,Redis重新发光(spirng redis)
- 利用Redis实现分布式爬虫(分布式 爬虫 redis)
- 通过Redis面试,把握大几率的成功(几率大的redis面试题)
- 完美解读Redis面试题库精选(redis面试题库大全)
- Redis集群模式存在的缺点(redis 集群模式缺点)
- 使用Redis锁定数据(redis里key锁)
- 通过Redis调整队列长度(redis 设置队列长度)
- Redis中的被动删除维护高性能(redis 被动删除)