Spring boot集成Redis实现sessions共享时,sessions过期时间问题分析
2024-09-04 08:07:24
Springboot鼓励零配置的方式,帮你做好大部分重复劳动的事,好到不能再好;具体的Redis安装方法和Springboot集成Redis方法,可以去搜索相关文章或参考该文章http://www.cnblogs.com/mengmeng89012/p/5519698.html。
当做用户权限管理时,一般都设置一个session过期时间,以确保用户长时间不操作时自动退出系统。
Spring seesions的原理可以参考该文章:http://blog.csdn.net/wojiaolinaaa/article/details/62424642
在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<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);
- }
最新文章
- Qt 5.2 Creator 和 vs2012 QT 插件的安装
- redhat下mysql安装与使用
- SSH 框架学习之初识Java中的Action、Dao、Service、Model-收藏
- [Jquery]滑动门效果
- oracle数据库导入导出命令!(转)
- [转]Avoiding GDB Signal Noise.
- 织梦CMS首页调用分类信息栏目及列表方法
- zuul入门(2)zuul的过滤器分类和加载
- 59A
- 2019.04.10打卡(HTML)
- rails5 后台入门(api mode)
- python-web自动化-三种等待方式
- Linksys EA6500刷ddwrt成功记
- [LeetCode] 20. Valid Parentheses_Easy tag: Stack
- 音频播放 音乐 MediaPlayer
- Linux 需要掌握的一些命令
- NNLearning阶段性总结01
- LeetCode第[13]题(Java):Roman to Integer
- CRF++评测脚本CoNLL 2000
- long_query_time 设置不生效问题