shiro + redis session过期时间不符合预期,提前过期
redis的过期时间设置的是8小时,如下
/** * 配置shiro redisManager * 使用的是shiro-redis开源插件 * * @return */ public RedisManager redisManager() { RedisManager redisManager = new RedisManager(); redisManager.setHost(hostIp); redisManager.setPort(6379); redisManager.setExpire(28800);// 配置缓存过期时间 redisManager.setTimeout(0); redisManager.setPassword(password); return redisManager; }
但登陆的用户莫名其妙在5小时甚至更短时间就session失效了
考虑到服务器内存有点吃力,就查了一下redis的内存淘汰机制,请参考:查看Redis的默认设置的过期策略和内存淘汰机制,当时发现默认的策略为:```noeviction``,
在此策略下如果缓存数据超过了maxmemory限定值,
并且客户端正在执行的命令(大部分的写
入指令,但DEL和几个指令例外)会导致内存分配,则向客户端返回错误响应
再登录redis查看一下maxmemory,请参考:查看redis占用内存大小以及其他运行信息,
发现竟然没有设置
那可能的原因就是内存不足了,key被清除了
既然如此 就设置一下redis.conf的maxmemory和配置一下内存淘汰策略
我设置的是 allkeys-lru,即在所有主键空间中,优先移除最近未使用的key
重启redis服务,重新测试,发现不会出现那种一会儿就失效的情况,但每次都在5小时后失效!!!
检查shiro配置发现如下:
//浏览器会话的cookie管理 @Bean(name = "sessionIdCookie") public SimpleCookie sessionIdCookie() { SimpleCookie cookie = new SimpleCookie(); cookie.setName("WEBS"); cookie.setHttpOnly(true); cookie.setMaxAge(18000); return cookie; }
原来罪魁祸首在这18000 ,正好等于5小时,看一下源码
public void setMaxAge(int maxAge) { this.maxAge = Math.max(DEFAULT_MAX_AGE, maxAge); }
其实不手动设置,它的默认值为-1,即只要浏览器不关闭,此cookie不失效!!!所以改为-1,或者删除它即可
总计一下:session过期时间与预期不符可能的原因有:
1、redis的key过期时间设置不当
2、redis的内存过期策略设置不当(包括最大内存maxmemory设置)
3、cookie过期时间设置不当