java实现redis过期机制_Spring boot集成Redis实现sessions共享时,sessions过期时间问题分析...

Springboot鼓励零配置的方式,帮你做好大部分重复劳动的事,好到不能再好;具体的Redis安装方法和Springboot集成Redis方法,可以去搜索相关文章或参考该文章http://www.cnblogs.com/mengmeng89012/p/5519698.html。

当做用户权限管理时,一般都设置一个session过期时间,以确保用户长时间不操作时自动退出系统。

在springboot中设置該值的方法如下:

@Configuration

@EnableRedisHttpSession(maxInactiveIntervalInSeconds= 3600,redisNamespace = "tl")

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 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 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);

}

来源:[]()

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值