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過期時間設定不當