分布式會話的演進和最佳實踐,含springBoot 實現(Java版本)

一、分布式會話的背景

在微服務架構或集群部署環境下,請求可能落在不同的服務器節點,無法再依賴本地內存來維護用戶 Session。因此,需要一種跨節點共享 Session 的機制,這就是 分布式會話管理的核心目標。


二、分布式會話的演進歷程

1. 單節點會話(原始方案)

  • 會話存儲在內存中,如 Tomcat 的 HttpSession。
  • 缺點:不可擴展節點故障丟失會話

2. Session Sticky(會話綁定)

  • 做法:使用負載均衡策略(如 Nginx 的 ip_hash)將同一用戶綁定到固定節點。

  • 優點:不用共享 Session。

  • 缺點:

    • 容錯差:節點掛了,Session 丟失。
    • 擴展性差:負載不均衡。

3. Session 復制(共享內存同步)

  • 如 Tomcat 集群通過 DeltaManagerBackupManager 實現 Session 同步。

  • 缺點:

    • 性能開銷大(尤其寫操作多時)。
    • 網絡帶寬壓力高。

4. 集中式 Session 存儲(核心階段)

  • 統一存儲于 Redis、Memcached、數據庫等。

  • 優點:

    • 節點無狀態,擴容方便。
    • 容錯好,支持持久化。
  • 常見技術棧:

    • Spring Session + Redis
    • Shiro + Redis
    • 自定義 Filter 攔截 + Redis
  • 缺點:

    • 讀寫 Redis 有延遲,需優化緩存與連接池。

5. Token 模式(Stateless Session)

  • 不再使用服務器記錄狀態。會話狀態由客戶端持有,常見如 JWT(JSON Web Token)。

  • 特點:

    • 完全無狀態,易于擴展。
    • 鑒權速度快,無需訪問服務器。
  • 缺點:

    • JWT 不支持撤銷。
    • Payload 泄漏風險需加密或簽名。
    • 會話失效處理復雜(需結合 Redis 存 token 黑名單等)。

6. 混合模式(最佳實踐)

  • 使用 JWT 攜帶身份信息 + Redis 存儲服務端狀態(權限、Session 信息等)。

  • 優點兼得:

    • 前端無狀態便于認證傳輸。
    • 服務端掌握可控狀態,支持注銷、權限變更等。

三、關鍵技術對比

模式狀態位置擴展性容錯性性能安全性實時性
Sticky Session服務端
Session 復制多服務端
Redis集中存儲Redis
JWT客戶端最好最好中(需加密)
混合方案客戶端+Redis最佳最佳中上最佳

四、最佳事件(Best Practices)

? 實際生產中推薦:

1. Spring Boot 項目:使用 Spring Session + Redis
  • 簡單集成,Spring 自動替換原生 Session。
  • 可配置 session TTL,支持自動刷新、分布式環境可控。
2. 高并發微服務:使用 JWT + Redis 雙模式
  • JWT 保證 stateless 高性能登錄認證。
  • Redis 存儲 session 黑名單、權限信息,便于集中管理。
3. 安全性要求高:JWT 簽名 + 加密 + Redis 控制權限變更
  • 對 token 加簽、加密(如 RSA)防篡改、防泄露。
  • Redis 控制 Token 生命周期、用戶禁用、權限升級等事件。
4. 高可用部署:Redis 使用 Sentinel / Cluster + 本地緩存
  • Redis 配合本地 Caffeine/Guava 緩存,減輕訪問壓力。
  • Redis 節點使用 Sentinel 做主從切換,確保高可用。
5. 重要業務審計:使用 Session ID 記錄登錄軌跡、權限行為
  • 配合 Kafka/Logstash 進行操作軌跡分析。

五、總結

分布式會話的演進反映了分布式系統對性能、可用性、安全性和擴展性的不斷追求。最佳實踐通常采用混合模式,兼顧無狀態特性與業務控制能力:

推薦組合:JWT(身份標識)+ Redis(狀態控制)+ 本地緩存(性能優化)+ Spring Security/Spring Session 集成

六、分布式會話最佳實踐之代碼實現

Spring Boot + Spring Security + JWT + Redis 的完整分布式會話控制實現


🧱 一、整體架構圖

[前端] ? [Spring Boot 接口層 (JWT Auth Filter)] ? [JWT 驗簽 + Redis 校驗] ? [業務接口]

📦 二、Maven 依賴

<!-- Spring Boot -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><!-- Spring Security -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency><!-- JWT -->
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version>
</dependency><!-- Redis -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

🔐 三、JWT 工具類

@Component
public class JwtUtil {private final String secretKey = "mySecretKey"; // 建議使用 RSA 非對稱密鑰private final long expiration = 60 * 60 * 1000; // 1小時public String generateToken(String username) {return Jwts.builder().setSubject(username).setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() + expiration)).signWith(SignatureAlgorithm.HS512, secretKey).compact();}public String getUsername(String token) {return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject();}public boolean isTokenValid(String token) {try {Claims claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();return claims.getExpiration().after(new Date());} catch (Exception e) {return false;}}
}

🔁 四、登錄接口

@RestController
@RequestMapping("/auth")
public class AuthController {@Autowired private JwtUtil jwtUtil;@Autowired private RedissonClient redissonClient;@PostMapping("/login")public ResponseEntity<?> login(@RequestBody Map<String, String> login) {String username = login.get("username");String password = login.get("password");//這里要寫業務代碼查詢用戶進行數據校驗 //獲取userId if ("admin".equals(username) && "123456".equals(password)) {String userId= "用戶ID";String token = jwtUtil.generateToken(username);RBucket<String> bucket = redissonClient.getBucket("TOKEN:" + userId);bucket.set(token, 30, TimeUnit.MINUTES);return ResponseEntity.ok(Map.of("token", token));}return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid credentials");}@PostMapping("/logout")public ResponseEntity<?> logout(HttpServletRequest request) {String token = request.getHeader("Authorization");if (token != null && token.startsWith("Bearer ")) {String jwt = token.substring(7);String userId= jwtUtil.getUsername(jwt);redissonClient.getBucket("TOKEN:" + userId).delete();}return ResponseEntity.ok("Logged out");}
}

🛡? 五、JWT 過濾器(攔截器)

@Component
public class JwtAuthFilter extends OncePerRequestFilter {@Autowired private JwtUtil jwtUtil;@Autowired private RedissonClient redissonClient;@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)throws ServletException, IOException {String authHeader = request.getHeader("Authorization");if (authHeader != null && authHeader.startsWith("Bearer ")) {String token = authHeader.substring(7);if (jwtUtil.isTokenValid(token)) {String userId = jwtUtil.getUsername(token); RBucket<String> bucket = redissonClient.getBucket("TOKEN:" + userId);String redisToken= bucket.get();boolean exists = bucket.isExists();if (exists && token.equals(redisToken)) {UsernamePasswordAuthenticationToken authentication =new UsernamePasswordAuthenticationToken(username, null, List.of());SecurityContextHolder.getContext().setAuthentication(authentication);}}}chain.doFilter(request, response);}
}

?? 六、Spring Security 配置

@Configuration
@EnableWebSecurity
public class SecurityConfig {@Autowired private JwtAuthFilter jwtAuthFilter;@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.csrf().disable().authorizeRequests().antMatchers("/auth/**").permitAll().anyRequest().authenticated().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);http.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);return http.build();}
}

🧪 七、測試方式

  1. 登錄

    • POST /auth/login,body:{ "username": "admin", "password": "123456" }
    • 返回 token
  2. 請求業務接口

    • GET /some/api,在 Header 中加 Authorization: Bearer <token>
  3. 退出登錄

    • POST /auth/logout,將當前 token 放入 Header

🧠 八、擴展建議(進階后續會不斷填坑)

功能需求建議方案
多端登錄互踢Redis 中存儲設備ID、時間戳,舊設備 token 作廢
Token 黑名單機制Redis 設置黑名單,配合 JWT ID(jti) 做驗證
細粒度權限控制搭配 Spring Security 的 @PreAuthorize@Secured 注解使用
Token 刷新機制定期發起 refresh token 請求,更新主 token
Redis 持久化或 Cluster開啟持久化,使用 Sentinel/Cluster 高可用

收工

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/87870.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/87870.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/87870.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ch03 部分題目思路

G. 收集 由于稀有度相同的物品需要一起處理&#xff0c;我們先把他們聚集到一起。 類似這樣&#xff1a; vector<int> g[maxn]; ... {cin >> x >> c;g[c].push_back(x); }那么我們需要一個貪心的思路&#xff1a; 肯定是按 ccc 從小往大收集的&#xff1b;對…

Django多表查詢(ORM)

1、建立表結構 三個表&#xff1a;book、Author、publisher。 書籍和作者是多對多的關系&#xff0c;一本書可以有多個作者&#xff0c;一個作者可以有多本書。 出版社和書籍是一對多的關系&#xff0c;一個出版社可以出版多本書&#xff08;多方&#xff0c;多方定義外鍵&…

C# 集合表達式和展開運算符 (..) 詳解

集合表達式 (Collection Expressions)基本語法支持的集合類型展開運算符 (..)基本用法實際應用示例創建新集合合并集合與現有API結合性能考慮高級用法多維集合自定義集合注意事項與傳統方式的比較總結集合表達式 (Collection Expressions) C# 12 引入了集合表達式&#xff0c;…

數學視頻動畫引擎Python庫 -- Manim Voiceover 安裝 Installation

文中內容僅限技術學習與代碼實踐參考&#xff0c;市場存在不確定性&#xff0c;技術分析需謹慎驗證&#xff0c;不構成任何投資建議。 Manim Voiceover 是一個為 Manim 打造的專注于語音旁白的插件&#xff1a; 直接在 Python 中添加語音旁白&#xff1a; 無需使用視頻編輯器&…

Git安裝避坑指南:新手村通關秘籍

Git安裝避坑指南&#xff1a;新手村通關秘籍 剛學編程那會兒&#xff0c;Git安裝差點讓我砸鍵盤。滿心歡喜打開官網下載&#xff0c;結果卡在配置上&#xff0c;命令行死活不認識git命令。看著教程里別人行云流水的操作&#xff0c;自己對著報錯信息干瞪眼——這感覺&#xff…

如何修改Siteground max_execution_time值?

這個值在Siteground 上是修改不了的。 以下是來自Siteground 官網的解釋&#xff1a; 由于服務器上全局定義的 PHP 限制&#xff0c;某些 PHP 設置無法更改。最常見的無法更改的 PHP 設置包括&#xff1a; memory_limit max_execution_time max_input_time post_max_size up…

【libm】 11 fmin函數 (fmin.rs)

一、源碼 這段代碼實現了一個符合 IEEE 754-2008 標準的 minNum 函數&#xff08;在 Rust 中命名為 fmin&#xff09;&#xff0c;該功能在 IEEE 754-2019 標準中已被 minimumNumber 取代。 /* SPDX-License-Identifier: MIT OR Apache-2.0 */ //! IEEE 754-2008 minNum. Thi…

React 英語單詞消消樂一款專為英語學習設計的互動式記憶游戲

&#x1f4d6; 項目簡介 英語單詞消消樂 是一款專為英語學習設計的互動式記憶游戲。通過經典的消消樂玩法&#xff0c;讓用戶在輕松愉快的游戲中掌握英語單詞&#xff0c;提高詞匯量和記憶效果。 &#x1f3af; 項目目標 讓英語學習變得有趣且高效通過游戲化方式增強單詞記憶…

Qt:QPushButton、QRadioButton、QCheckBox

目錄 一、QPushButton 1.認識QPushButton 2.設置按鈕圖標 3.設置按鈕的快捷鍵 二、QRadioButton 常用的信號 按鈕的分組 三、QCheckBox 一、QPushButton 1.認識QPushButton QPushButton繼承自QWidget&#xff0c;所以在上一篇文章中介紹的QWidget的屬性&#xff0c;理…

docker 無法拉取鏡像解決方法

目錄 我在omv中通過后臺頁面拉取alist鏡像總是失敗&#xff0c;原因千奇百怪 今天再戰終于解決首先&#xff0c;到dockerhub找鏡像和wiki進入docker賬號設置 找到里面提示了登錄操作和密碼命令行中執行后會提示成功之后按需配置代理&#xff0c;同時檢查自己的配置檢查 Docker …

安卓10.0系統修改定制化_____安卓9與安卓10系統文件差異 有關定制選項修改差異

在修改安卓10的rom之前。我們需要對rom有簡單的了解。區分安卓10與安卓9之間的差異。了解不同安卓版本之間系統文件的變化以及權限的區別。對于修改一些定制化選項有很大的輔助作用. 通過博文了解?????? 1??????-----安卓10與安卓9之間文件實例對比 了解差異 …

HTML表單元素全面指南:從基礎到實踐

引言 HTML表單是網頁開發中不可或缺的一部分&#xff0c;它為用戶提供了與網站交互的途徑。無論是簡單的登錄頁面還是復雜的數據提交界面&#xff0c;表單元素都扮演著關鍵角色。本文將詳細介紹各種HTML表單元素及其使用方法。 輸入框(input元素) input元素是最基礎也是最靈…

深度學習的核心理論與技術

理解深度學習的基本原理、核心算法和關鍵技術 深度學習的核心理論與技術前言一、深度學習核心理論1. 神經網絡基礎核心內容練習資源2. 反向傳播與梯度下降核心內容練習資源3. 卷積神經網絡&#xff08;CNN&#xff09;核心內容練習資源4. 循環神經網絡&#xff08;RNN&#xff…

LinkedList 鏈表數據結構實現 (OPENPPP2)

&#x1f50d; LinkedList 鏈表數據結構實現 (OPENPPP2) &#x1f9f1; 1. 數據結構設計 LinkedListNode 結構 #mermaid-svg-XDJqt6cHMKxodJLG {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-XDJqt6cHMKxodJLG .er…

RPC/gRPC入門學習

一、RPC 1.1 RPC概念 RPC Remote Procedure Call, 即遠程過程調用&#xff0c;是一種用于構建分布式系統的理念&#xff0c;在一些資料中被稱為“請求-響應”協議。兩個進程可以位于同一系統中&#xff0c;也可以位于不同的系統中&#xff0c;通過網絡相互連接。 RPC使程…

租車小程序電動車租賃小程序php方案

電動車租賃小程序源碼&#xff0c;開發語言后端php&#xff0c;前端uniapp。四個端&#xff1a;用戶端門店端分銷商端小程序&#xff0c;pc管理后臺。一 用戶端&#xff1a;可以掃門店碼&#xff0c;進入門店詳情頁。也可以通過地圖找車。或者門店列表進入&#xff0c;或者快速…

Python數據分析基礎04:預測性數據分析

相關章節&#xff1a; 《Python數據分析基礎03&#xff1a;探索性數據分析》 《python數據分析基礎02&#xff1a;數據可視化分析》 《Python數據分析基礎01&#xff1a;描述性統計分析》 預測性數據分析&#xff08;Predictive Analytics&#xff09; 的深度解析&#xff0…

PFAE(Pyramidal Frequency Attention Extraction)通過頻域注意力機制提高邊界模糊、遮擋等場景的的檢測能力

在偽裝物體檢測中&#xff0c;現有方法多依賴空間局部特征&#xff0c;難以捕捉全局信息&#xff0c;而 Transformer 類方法計算成本高昂。頻率域特征因具備全局建模能力&#xff0c;可有效抑制背景噪聲、提升偽裝物體語義清晰度&#xff0c;但頻域與空域的頻繁轉換會增加計算復…

AE插件安裝方法

Adobe After Effects簡稱AE&#xff0c;是adobe公司開發的一個視頻剪輯及設計軟件&#xff0c;AE軟件能夠實現對素材的非線性編輯而完成畫面的組接&#xff0c;同時還能對任何一部分進行修改&#xff0c;達到想要的結果。AE含有很多腳本、常用的表達式和插件&#xff0c;做動畫…

舵輪時鐘-STM32-28路PWM--ESP8266-NTP時間

1.STM32--PWM生成STM32不具備如此多的PWM&#xff0c;因此采用軟件定時器的方案實現&#xff1a;使用hal庫實現&#xff1b;main.c#include "main.h"#define close1 500#define open 1500#define close 2500// 定時器中斷配置&#xff08;以TIM2為例&#xff09; voi…