搜尋
首頁Javajava教程SpringBoot怎麼整合Spring Session實現分散式會話

Spring 提供了處理分散式會話的解決方案:Spring-Session。 Spring-Session 提供了對Redis、MongoDB、MySQL 等常用儲存的支持,Spring-Session 提供與 HttpSession 的透明整合,這意味著開發人員可以使用 Spring-Session 支援的實作方式,切換 HttpSession 至 Spring-Session。

一、設定及開發

Step 1、新增依賴

在專案的pom.xml 檔案中加入Redis 和Spring-Session 的依賴包。

        <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>

Step 2、配置Redis 和Spring-Session 持久化方式

筆者習慣使用application.properties 作為SpringBoot 的配置文件,也可以使用application.yml 來配置。在 application.properties 設定檔中新增如下配置。

# 配置 Redis 服务器地址(此处是一个虚假地址)
spring.redis.host=10.211.12.6
# 配置 Redis 端口
spring.redis.port=6379
# 配置 Redis 密码
spring.redis.password=123456
# 其他 Redis 的配置还有很多,例如 Redis 连接池的配置,此处暂时只配置上述几项关键点
# spring session 配置
spring.session.store-type=redis

Step 3、使用JSON 序列化機制

Spring-Session 預設使用JDK 序列化機制,要求類別實作Serializable 接口,序列化後是二進位位元組數組,不易看懂。使用 JSON 序列化機制,序列化後的字串容易看懂。

package com.test.conf;

import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.serializer.RedisSerializer;

// spring session 使用 json 序列化机制
@Configuration
public class SessionConfig {
    @Bean
    public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
        return new GenericFastJsonRedisSerializer();
    }
}

Step 4、在 SpringBoot 啟動類別中新增 @EnableRedisHttpSession 註解,開啟 Spring-Session

package com.test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

@SpringBootApplication
// 开启 Spring-Session
@EnableRedisHttpSession
// @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800, redisNamespace = "test:session")
public class TestSessionAppApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestSessionAppApplication.class, args);
    }
}

 打上 @EnableRedisHttpSession 註解即可開啟 Spring-Session。註解有幾個參數可以單獨設置,其中maxInactiveIntervalInSeconds 表示Session 過期時間,預設值是30 分鐘;redisNamespace 表示Session 在Redis 中儲存時的命名空間,即Session 在Redis 中儲存的鍵名前綴,預設值是「spring :session”,在實際專案中,可能不同的系統為了節約資源,會使用同一個Redis,為了區分不同系統的Session,可以為每個系統設定單獨的命名空間。

二、測試

2.1 controller 層編寫測試demo

    @RequestMapping(value = "testSession")
    public String testSession(HttpServletRequest request) {
        HttpSession session = request.getSession();
        log.info("sessionId:[{}]", session.getId());
        session.setAttribute("name", "Lucy");
        session.setAttribute("age", "20");
        return session.getAttribute("name").toString();
    }

2.2 測試過程

同時以不同的連接埠9001/9002 啟動SpringBoot 項目,在本機電腦上模擬分散式叢集中的不同節點。用Google瀏覽器開啟連結 http://localhost:9001/testSession,服務端列印日誌如下所示。

sessionId:[5c417104-4f6d-430d-b569-cbc1e19cdf02]

用戶端登入 Redis 伺服器,查看 Redis 中的 Session 內容。

[testuser@vm ~]$ redis-cli -h 10.211.12.6 -p 6379
10.211.12.6:6379> auth 123456
OK
10.211.12.6:6379> keys *
1) "spring:session:expirations:1658127780000"
2) "spring:session:sessions:5c417104-4f6d-430d-b569-cbc1e19cdf02"
3) "spring:session:sessions:expires:5c417104-4f6d-430d-b569-cbc1e19cdf02"

Redis 會為每個RedisSession 儲存三個鍵值對(以下簡稱key-value):

  • 第一個key-value 儲存這個Session 的Id ,是一個Set 類型的Redis 資料結構。這個 key 中的最後的 1658127780000 值是一個時間戳,根據這個 Session 過期時刻滾動至下一分鐘而計算得出。

  • 第二個key-value 用來儲存Session 的詳細信息,是一個Hash 類型的Redis 資料結構,包括Session 的最近存取時間(lastAccessedTime)、過期時間間隔(maxInactiveInterval ,預設是30 分鐘,這裡儲存的秒值)、建立時間(creationTime)、sessionAttr 等等。

  • 第三個 key-value 用來表示 Session 在 Redis 中的過期時間,是一個 String 類型的 Redis 資料結構。這個 key-value 不儲存任何有用數據,只是為表示 Session 過期而設定。這個 key 在 Redis 中的過期時間即為 Session 的過期時間間隔,可以用 ttl 指令查看該 key 的過期時間,即為 Session 的過期時間。

本次測試時,Redis 中的資料詳情如下所示。

10.211.12.6:6379> type spring:session:expirations:1658127780000
set
10.211.12.6:6379> smembers spring:session:expirations:1658127780000
1) "\"expires:5c417104-4f6d-430d-b569-cbc1e19cdf02\""
10.211.12.6:6379>
10.211.12.6:6379> type spring:session:sessions:5c417104-4f6d-430d-b569-cbc1e19cdf02
hash
10.211.12.6:6379> hgetall spring:session:sessions:5c417104-4f6d-430d-b569-cbc1e19cdf02
 1) "lastAccessedTime"
 2) "1658125969794"
 3) "maxInactiveInterval"
 4) "1800"
 5) "creationTime"
 6) "1658125925139"
 7) "sessionAttr:age"
 8) "\"20\""
 9) "sessionAttr:name"
10) "\"Lucy\""
10.211.12.6:6379>
10.211.12.6:6379> type spring:session:sessions:expires:5c417104-4f6d-430d-b569-cbc1e19cdf02
string
10.211.12.6:6379> get spring:session:sessions:expires:5c417104-4f6d-430d-b569-cbc1e19cdf02
""
10.201.42.26:6379>

查看瀏覽器 Cookie,此時瀏覽器已經有了一個正在使用的 Cookie,請見下圖。

SpringBoot怎么整合Spring Session实现分布式会话

刷新瀏覽器,後端列印的 SessionId 不變,Redis 中的 Session 內容未新增,瀏覽器正常回傳內容。說明本節點操作 Session 正常。

同一瀏覽器,開啟另一個測試連接埠連結http://localhost:9002/testSession,瀏覽器自動攜帶Cookie,後端列印內容相同,Redis 內容相同(過期時間已更新),說明集群節點之間共享了Session。

三、Spring-Session 的缺點

雖然Spring-Session 提供了一種簡單易用,近乎透明的集成方式,使得支持集群會話變得微不足道,但是實際上Spring- Session 是有些缺陷的。

  • 無法做到Session 的過期以及銷毀事件的即時發布;

  • 序列化方式可能對一些特定類型的會話,支援的不是很好;

  • Redis 儲存一個會話需要3 個鍵值,佔用空間稍微大些;

  • 在高並發場景下, Session 因為不是CAS(Compare And Set) 操作,所以可能會有一些並發問題(小問題)。

雖然 Spring-Session 存在一些缺點,但整體來說還是可用性很高的。另外自己可以寫一套過濾器,優化 Spring-Session 的缺點,實現分散式會話。

以上是SpringBoot怎麼整合Spring Session實現分散式會話的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:亿速云。如有侵權,請聯絡admin@php.cn刪除
Java開發的哪些方面取決於平台?Java開發的哪些方面取決於平台?Apr 26, 2025 am 12:19 AM

JavadevelovermentIrelyPlatForm-DeTueTososeVeralFactors.1)JVMVariationsAffectPerformanceNandBehaviorAcroSsdifferentos.2)Nativelibrariesviajnijniiniininiinniinindrododerplatefform.3)

在不同平台上運行Java代碼時是否存在性能差異?為什麼?在不同平台上運行Java代碼時是否存在性能差異?為什麼?Apr 26, 2025 am 12:15 AM

Java代碼在不同平台上運行時會有性能差異。 1)JVM的實現和優化策略不同,如OracleJDK和OpenJDK。 2)操作系統的特性,如內存管理和線程調度,也會影響性能。 3)可以通過選擇合適的JVM、調整JVM參數和代碼優化來提升性能。

Java平台獨立性有什麼局限性?Java平台獨立性有什麼局限性?Apr 26, 2025 am 12:10 AM

Java'splatFormentenceHaslimitations不包括PerformanceOverhead,versionCompatibilityIsissues,挑戰WithnativelibraryIntegration,Platform-SpecificFeatures,andjvminstallation/jvminstallation/jvmintenance/jeartenance.therefactorscomplicatorscomplicatethe“ writeOnce”

解釋平台獨立性和跨平台發展之間的差異。解釋平台獨立性和跨平台發展之間的差異。Apr 26, 2025 am 12:08 AM

PlatformIndependendecealLowsProgramStormonanyPlograwsStormanyPlatFormWithOutModification,而LileCross-PlatFormDevelopmentRequiredquiresMomePlatform-specificAdjustments.platFormIndependence,EneblesuniveByjava,EnablesuniversUniversAleversalexecutionbutmayCotutionButMayComproMisePerformance.cross.cross.cross-platformd

即時(JIT)彙編如何影響Java的性能和平台獨立性?即時(JIT)彙編如何影響Java的性能和平台獨立性?Apr 26, 2025 am 12:02 AM

JITcompilationinJavaenhancesperformancewhilemaintainingplatformindependence.1)Itdynamicallytranslatesbytecodeintonativemachinecodeatruntime,optimizingfrequentlyusedcode.2)TheJVMremainsplatform-independent,allowingthesameJavaapplicationtorunondifferen

為什麼Java是開發跨平台桌面應用程序的流行選擇?為什麼Java是開發跨平台桌面應用程序的流行選擇?Apr 25, 2025 am 12:23 AM

javaispopularforcross-platformdesktopapplicationsduetoits“ writeonce,runany where”哲學。 1)itusesbytiesebyTecodeThatrunsonAnyJvm-備用Platform.2)librarieslikeslikeslikeswingingandjavafxhelpcreatenative-lookingenative-lookinguisis.3)

討論可能需要在Java中編寫平台特定代碼的情況。討論可能需要在Java中編寫平台特定代碼的情況。Apr 25, 2025 am 12:22 AM

在Java中編寫平台特定代碼的原因包括訪問特定操作系統功能、與特定硬件交互和優化性能。 1)使用JNA或JNI訪問Windows註冊表;2)通過JNI與Linux特定硬件驅動程序交互;3)通過JNI使用Metal優化macOS上的遊戲性能。儘管如此,編寫平台特定代碼會影響代碼的可移植性、增加複雜性、可能帶來性能開銷和安全風險。

與平台獨立性相關的Java開發的未來趨勢是什麼?與平台獨立性相關的Java開發的未來趨勢是什麼?Apr 25, 2025 am 12:12 AM

Java將通過雲原生應用、多平台部署和跨語言互操作進一步提昇平台獨立性。 1)雲原生應用將使用GraalVM和Quarkus提升啟動速度。 2)Java將擴展到嵌入式設備、移動設備和量子計算機。 3)通過GraalVM,Java將與Python、JavaScript等語言無縫集成,增強跨語言互操作性。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)