天天看點

shiro + redis session過期時間不符合預期,提前過期

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