1. 程式人生 > 其它 >springboot+spring-session

springboot+spring-session

1. 實現背景

      測試環境上部署了一個單機專案,專案的context-path為空,之後再經過nginx的轉發進行部署,專案可以正常進行登入等等一系列操作;生產環境跟測試環境程式碼完全相同,只是相關的專案配置包括nginx配置不同,專案可以正常啟動,但登入失敗。原本以為是nginx相關的配置有問題,導致調完登入介面,返回的cookie中攜帶的專案名不一致導致的。經過檢查發現登入介面返回的cookie中跟後續請求的cookie中的引數一致,所以跟配置無關。最後發現生產配置的專案是叢集模式,所以根本還是出現在session共享上面。

2.具體實現

   這裡做的共享session用的是redis,所以要安裝redis並引入相關依賴;

<!--session-->
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>
<!-- redis依賴配置 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

   其次application.yml中新增相關配置

spring:
   session:
      store-type: redis #是否將session存到redis  none/redis
      timeout: 1800 # 配置session在redis中的過期時間
      redis:
      flush-mode: immediate #儲存時重新整理,即響應結束後重新整理。預設是 on_save;immediate實時重新整理
      namespace: smith:session #預設是spring:session
   redis:
      host: 
127.0.0.1 # Redis伺服器地址 database: 0 # Redis資料庫索引(預設為0) port: 6379 # Redis伺服器連線埠 password: # Redis伺服器連線密碼(預設為空) timeout: 3000ms # 連線超時時間

    到這裡配置工作就完成了,啟動專案即可。

3. 錯誤資訊

 org.springframework.boot.autoconfigure.session.SessionRepositoryUnavailableException: No session repository could be auto-configured, check your configuration (session store type is 'redis')

    因為當store-type配置為redis的時候,redis是需要序列化的,所以我們還需要對restTemplate進行序列化,至此問題解決,專案可成功啟動。

@Configuration
public class RedisConfiguration {
    /**
     * @param redisConnectionFactory:配置不同的客戶端,這裡注入的redis連線工廠不同: JedisConnectionFactory、LettuceConnectionFactory
     * @功能描述 :配置Redis序列化,原因如下:
     * (1) StringRedisTemplate的序列化方式為字串序列化,
     * RedisTemplate的序列化方式默為jdk序列化(實現Serializable介面)
     * (2) RedisTemplate的jdk序列化方式在Redis的客戶端中為亂碼,不方便檢視,
     * 因此一般修改RedisTemplate的序列化為方式為JSON方式【建議使用GenericJackson2JsonRedisSerializer】
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        // key採用String的序列化方式
        redisTemplate.setKeySerializer(StringRedisSerializer.UTF_8);
        // value序列化方式採用jackson
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的key也採用String的序列化方式
        redisTemplate.setHashKeySerializer(StringRedisSerializer.UTF_8);
        //hash的value序列化方式採用jackson
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        return redisTemplate;
    }
}

 4. 總結

    當叢集模式時候,需要將登入相關資訊儲存在redis或其他資料庫中實現共享,也就是說sessionid儲存在客戶端的cookie裡面,然後將該sessionid作為key將session儲存在redis服務端。當部署很多個專案時候,因為session-namespace是預設值,所以可以修改namespace的值,把不同專案區分開。