Spring-SpringSession 介紹和使用

一、 HttpSession 回顧

什麼是 HttpSession
是 JavaWeb 服務端提供的用來建立與客戶端會話狀態的對象。

二、 Session 共享

什麼是 Session 共享

是指在一個瀏覽器訪問多個 Web 服務時,服務端的 Session 數據需要共享。

Session 共享應用場景

List item單點登錄
Web 服務器集羣等場景

Session 共享常見的解決方案

Session 複製
通過對應用服務器的配置開啓服務器的 Session 複製功能,在集羣中的幾臺服務器之間同步 Session 對象,使得每臺服務器上都保存所有的 Session 信息,這樣任何一臺宕機都不會導致 Session 的數據丟失,服務器使用 Session 時,直接從本地獲取。這種方式的缺點也比較明顯。因爲 Session 需要時時同步,並且同步過程是有應用服務器來完成,由此對服務器的性能損耗也比較大。

Session 綁定
利用 hash 算法,比如 nginx 的 ip_hash,使得同一個 Ip 的請求分發到同一臺服務器上。 這種方式不符合對系統的高可用要求,因爲一旦某臺服務器宕機,那麼該機器上的 Session 也就不復存在了,用戶請求切換到其他機器後麼有 Session,無法完成業務處理。

利用 Cookie 記錄 Session
Session 記錄在客戶端,每次請求服務器的時候,將 Session 放在請求中發送給服務器, 服務器處理完請求後再將修改後的 Session 響應給客戶端。這裏的客戶端就是 cookie。 利用 cookie 記錄 Session 的也有缺點,比如受 cookie 大小的限制,能記錄的信息有限, 安全性低,每次請求響應都需要傳遞 cookie,影響性能,如果用戶關閉 cookie,訪問就不正常。

Session 服務器
Session 服務器可以解決上面的所有的問題,利用獨立部署的 Session 服務器統一管理 Session,服務器每次讀寫 Session 時,都訪問 Session 服務器。 對於 Session 服務器,我們可以使用 Redis 或者 MongoDB 等內存數據庫來保存 Session 中的數據,以此替換掉服務中的 HttpSession。達到 Session 共享的效果。

三、SpringSession的簡介

Spring Session 是 Spring 的項目之一。Spring Session 提供了一套創建和管理 Servlet HttpSession 的方案,默認採用外置的 Redis 來存儲 Session 數據,以此來解決 Session 共享的 問題。

四、集成SpringSession

1、傳統項目繼承

Maven中pom.xml文件中添加(選一種添加上就行):

<span style="white-space:pre">    </span><!--1、redis-整合--> 
    <dependency> 
      <groupId>org.springframework.session</groupId> 
      <artifactId>spring-session-data-redis</artifactId> 
      <version>1.0.2.RELEASE</version> 
    </dependency> 
    <!-- 2、Redis --> 
    <dependency> 
      <groupId>org.springframework.data</groupId> 
      <artifactId>spring-data-redis</artifactId> 
      <version>1.4.2.RELEASE</version> 
    </dependency>    
    <dependency> 
      <groupId>redis.clients</groupId> 
      <artifactId>jedis</artifactId> 
      <version>2.5.2</version> 
    </dependency> 
    <dependency> 
        <groupId>org.springframework.session</groupId> 
        <artifactId>spring-session</artifactId> 
        <version>1.0.2.RELEASE</version> 
    </dependency> 
    <dependency> 
       <groupId>org.apache.commons</groupId> 
       <artifactId>commons-pool2</artifactId> 
       <version>2.2</version> 
    </dependency>

在spring配置文件(applicationContext.xml)中添加代碼:

<span style="white-space:pre">  </span><!-- 自動掃描 --> 
   <context:annotation-config/> 
  <!-- 配置spring-session -->  
  <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">  
    <!-- 過期時間100分鐘 --> 
    <property name="maxInactiveIntervalInSeconds" value="6000"></property> 
  </bean>  
  <!-- redis連接池 --> 
  <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig" />  
  <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >  
    <property name="hostName" value="10.4.120.180" />  
    <property name="port" value="6379" />  
    <property name="poolConfig" ref="jedisPoolConfig" />  
  </bean>

在web.xml中添加過濾即可:

<span style="white-space:pre">  </span><!-- Spring Session的Filter --> 
  <filter> 
    <filter-name>springSessionRepositoryFilter</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
  </filter> 
  <filter-mapping> 
    <filter-name>springSessionRepositoryFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
  </filter-mapping> 
  <session-config> 
    <session-timeout>30</session-timeout> 
  </session-config>  

這樣就自動將session放入到reids庫中了。

Sringboot項目集成SpringSessoin

1. pom.xml中引入jar包

<!-- Spring Boot Redis 依賴 -->
 <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis</artifactId>
 </dependency>  
  <dependency> 
    <groupId>org.springframework.session</groupId> 
    <artifactId>spring-session-data-redis</artifactId> 
 </dependency>   
 <dependency>
   <groupId>org.springframework.session</groupId>
   <artifactId>spring-session-core</artifactId>
 </dependency>

添加RedisSessionConfig配置類
在項目的目錄中,創建一個java文件(名稱隨意)即可,我這裏名稱是RedisSessionConfig.java
@EnableRedisHttpSession這個註解非常最重要,加了它之後,會使用spring的一個攔截器來實現Session共享的操作,而配置的這個Bean,則是讓Spring根據配置文件中的配置連到Redis。
SpringSession 需要注意的就是redis需要2.8以上版本,然後開啓事件通知,在redis配置文件裏面加上

notify-keyspace-events Ex // 打開此配置,其中Ex表示鍵事件通知裏面的key過期事件,每當有過期鍵被刪除時,會發送通知

或是使用如下命令開啓開啓事件通知:

redis-cli config set notify-keyspace-events Egx

如果你的Redis不是你自己維護的,比如你是使用阿里雲的Redis數據庫(我就是這種情況),你不能夠更改它的配置,那麼可以使用下面的java配置文件即可。

package org.spring.springboot.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.data.redis.config.ConfigureRedisAction;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

@Configuration
// maxInactiveIntervalInSeconds 默認是1800秒過期,這裏測試修改爲60秒
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)
public class RedisSessionConfig { 
 @Bean
 public static ConfigureRedisAction configureRedisAction() {
 return ConfigureRedisAction.NO_OP;
 }
}

3. 配置redis連接

Spring Boot會自動創建一個RedisConnectionFactory將Spring Session連接到端口6379(默認端口)上localhost上的Redis服務器的連接。在生產環境中,您需要確保更新配置以指向Redis服務器

src/main/resources/application.properties

# Redis 配置
# Redis數據庫索引(默認爲0)
spring.redis.database=0
# Redis服務器地址
spring.redis.host=192.168.0.1
# Redis服務器連接端口
spring.redis.port=6379
# Redis服務器連接密碼(默認爲空)
spring.redis.password=1234

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章