Spring boot集成Redis實現sessions共享時,sessions過期時間問題分析


    Springboot鼓勵零配置的方式,幫你做好大部分重復勞動的事,好到不能再好;具體的Redis安裝方法和Springboot集成Redis方法,可以去搜索相關文章或參考該文章http://www.cnblogs.com/mengmeng89012/p/5519698.html。

 

當做用戶權限管理時,一般都設置一個session過期時間,以確保用戶長時間不操作時自動退出系統。

Spring seesions的原理可以參考該文章:http://blog.csdn.net/wojiaolinaaa/article/details/62424642

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

 

  1.  
    @Configuration
  2.  
    @EnableRedisHttpSession(maxInactiveIntervalInSeconds= 3600,redisNamespace = "tl")
  3.  
    public class RedisSessionConfig {
  4.  
     
  5.  
    }

 

即開啟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函數:

  1.  
    public void setImportMetadata(AnnotationMetadata importMetadata) {
  2.  
     
  3.  
    Map<String, Object> enableAttrMap = importMetadata
  4.  
    .getAnnotationAttributes(EnableRedisHttpSession.class.getName());
  5.  
    AnnotationAttributes enableAttrs = AnnotationAttributes.fromMap(enableAttrMap);
  6.  
    /**
  7.  
    *解析注解,獲取maxInactiveIntervalInSeconds賦值給配置類的maxInactiveIntervalInSeconds對象
  8.  
    */
  9.  
    this.maxInactiveIntervalInSeconds = enableAttrs
  10.  
    .getNumber("maxInactiveIntervalInSeconds");
  11.  
    String redisNamespaceValue = enableAttrs.getString("redisNamespace");
  12.  
    /**
  13.  
    *設置命名空間
  14.  
    */
  15.  
    if (StringUtils.hasText(redisNamespaceValue)) {
  16.  
    this.redisNamespace = this.embeddedValueResolver.resolveStringValue(redisNamespaceValue);
  17.  
    }
  18.  
    this.redisFlushMode = enableAttrs.getEnum("redisFlushMode");
  19.  
    }
	利用Redis作為sessions共享倉實現類為org.springframework.session.data.redis.RedisOperationsSessionRepository
其執行session過期策略的實現類為RedisSessionExpirationPolicy,其過期的具體函數如下:
  1.  
    public void onExpirationUpdated(Long originalExpirationTimeInMilli,
  2.  
    ExpiringSession session) {
  3.  
    String keyToExpire = "expires:" + session.getId();
  4.  
    long toExpire = roundUpToNextMinute(expiresInMillis(session));
  5.  
     
  6.  
    if (originalExpirationTimeInMilli != null) {
  7.  
    long originalRoundedUp = roundUpToNextMinute(originalExpirationTimeInMilli);
  8.  
    if (toExpire != originalRoundedUp) {
  9.  
    String expireKey = getExpirationKey(originalRoundedUp);
  10.  
    this.redis.boundSetOps(expireKey).remove(keyToExpire);
  11.  
    }
  12.  
    }
  13.  
     
  14.  
    long sessionExpireInSeconds = session.getMaxInactiveIntervalInSeconds();
  15.  
    String sessionKey = getSessionKey(keyToExpire);
  16.  
     
  17.  
    if (sessionExpireInSeconds < 0) {
  18.  
    this.redis.boundValueOps(sessionKey).append("");
  19.  
    this.redis.boundValueOps(sessionKey).persist();
  20.  
    this.redis.boundHashOps(getSessionKey(session.getId())).persist();
  21.  
    return;
  22.  
    }
  23.  
     
  24.  
    String expireKey = getExpirationKey(toExpire);
  25.  
    BoundSetOperations<Object, Object> expireOperations = this.redis
  26.  
    .boundSetOps(expireKey);
  27.  
    expireOperations.add(keyToExpire);
  28.  
    /**
  29.  
    *關鍵在此處,在設置的基礎上增加了5分鍾
  30.  
    /
  31.  
    long fiveMinutesAfterExpires = sessionExpireInSeconds
  32.  
    + TimeUnit.MINUTES.toSeconds(5);
  33.  
     
  34.  
    expireOperations.expire(fiveMinutesAfterExpires, TimeUnit.SECONDS);
  35.  
    if (sessionExpireInSeconds == 0) {
  36.  
    this.redis.delete(sessionKey);
  37.  
    }
  38.  
    else {
  39.  
    this.redis.boundValueOps(sessionKey).append("");
  40.  
    this.redis.boundValueOps(sessionKey).expire(sessionExpireInSeconds,
  41.  
    TimeUnit.SECONDS);
  42.  
    }
  43.  
    this.redis.boundHashOps(getSessionKey(session.getId()))
  44.  
    .expire(fiveMinutesAfterExpires, TimeUnit.SECONDS);
  45.  
    }
  46.  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM