Redis與session使用及說(shuō)明
一、傳統(tǒng) Session:服務(wù)器內(nèi)存中的用戶狀態(tài)容器
1. 本質(zhì)與核心功能
Session(會(huì)話)是 Web 服務(wù)器(如 Tomcat)為解決 HTTP 協(xié)議 “無(wú)狀態(tài)性” 而設(shè)計(jì)的 服務(wù)器端狀態(tài)存儲(chǔ)機(jī)制。其核心功能是:
- 為每個(gè)用戶生成唯一標(biāo)識(shí)(
sessionId),關(guān)聯(lián)用戶的連續(xù)請(qǐng)求; - 存儲(chǔ)用戶的臨時(shí)狀態(tài)信息(如登錄狀態(tài)、購(gòu)物車數(shù)據(jù)、權(quán)限標(biāo)識(shí)等),實(shí)現(xiàn) “用戶身份跟蹤”。
2. 內(nèi)部結(jié)構(gòu)與核心屬性
傳統(tǒng) Session(以 Java Web 的HttpSession為例)本質(zhì)是 服務(wù)器內(nèi)存中的一個(gè) “鍵值對(duì)對(duì)象”,結(jié)構(gòu)可拆解為:
| 屬性 / 組件 | 說(shuō)明 |
|---|---|
| sessionId | 唯一標(biāo)識(shí)(字符串,如6F9619FF-8B86-D011-B42D-00C04FC964FF),由服務(wù)器隨機(jī)生成,用于關(guān)聯(lián)客戶端請(qǐng)求。 |
| attributes | 核心存儲(chǔ)區(qū)(Map<String, Object>結(jié)構(gòu)),存儲(chǔ)用戶數(shù)據(jù)(如userId=1001、username="張三"、cart={...})。 |
| 生命周期參數(shù) | maxInactiveInterval:最大空閑時(shí)間(默認(rèn) 30 分鐘,超時(shí)自動(dòng)失效);creationTime/lastAccessedTime:創(chuàng)建與最后訪問(wèn)時(shí)間,用于判斷是否超時(shí)。 |
| 狀態(tài)標(biāo)識(shí) | isNew():判斷是否為新會(huì)話;isValid():判斷會(huì)話是否有效(未過(guò)期 / 未銷毀)。 |
3. 與 Tomcat 服務(wù)器的強(qiáng)綁定機(jī)制
傳統(tǒng) Session 的存儲(chǔ)與管理完全依賴 單個(gè) Web 服務(wù)器實(shí)例(如 Tomcat),具體表現(xiàn)為:
- 存儲(chǔ)位置:Session 數(shù)據(jù)保存在當(dāng)前 Tomcat 進(jìn)程的內(nèi)存中(非磁盤(pán)),屬于 “進(jìn)程內(nèi)數(shù)據(jù)”。
- 管理主體:Tomcat 通過(guò)內(nèi)置的
SessionManager組件管理所有 Session,包括創(chuàng)建、查詢、過(guò)期清理等(默認(rèn)每 60 秒掃描一次過(guò)期 Session)。 - 隔離性:不同 Tomcat 實(shí)例的內(nèi)存相互獨(dú)立,A 服務(wù)器的 Session 無(wú)法被 B 服務(wù)器訪問(wèn)(內(nèi)存隔離是分布式場(chǎng)景的核心痛點(diǎn))。
4. 生命周期(以用戶登錄為例)
創(chuàng)建:用戶首次訪問(wèn)需要狀態(tài)跟蹤的接口(如登錄)時(shí),Tomcat 生成sessionId,創(chuàng)建 Session 對(duì)象并存儲(chǔ)用戶信息。
傳遞:服務(wù)器通過(guò) HTTP 響應(yīng)頭的Set-Cookie將sessionId發(fā)送給客戶端,客戶端后續(xù)請(qǐng)求通過(guò) Cookie 自動(dòng)攜帶sessionId。
活躍:用戶持續(xù)操作時(shí),Tomcat 通過(guò)sessionId找到對(duì)應(yīng) Session,更新lastAccessedTime(避免超時(shí))。
過(guò)期 / 銷毀:
- 超時(shí):用戶超過(guò)
maxInactiveInterval未操作,Tomcat 自動(dòng)銷毀 Session; - 主動(dòng)銷毀:調(diào)用
session.invalidate()(如用戶退出登錄); - 服務(wù)器重啟:內(nèi)存中的 Session 全部丟失(無(wú)持久化)。
5. 局限性(分布式場(chǎng)景下)
傳統(tǒng) Session 在單機(jī)應(yīng)用中可行,但在分布式部署(多服務(wù)器集群)或高并發(fā)場(chǎng)景中存在致命問(wèn)題:
- 會(huì)話共享問(wèn)題:用戶請(qǐng)求被負(fù)載均衡分發(fā)到不同服務(wù)器時(shí),新服務(wù)器無(wú)用戶 Session,導(dǎo)致 “登錄狀態(tài)失效”(如用戶在 Tomcat A 登錄,下次請(qǐng)求到 Tomcat B 時(shí)被判定為未登錄)。
- 內(nèi)存限制:Session 存儲(chǔ)在服務(wù)器內(nèi)存,用戶量增長(zhǎng)會(huì)導(dǎo)致內(nèi)存占用飆升,甚至引發(fā) OOM(內(nèi)存溢出)。
- 無(wú)持久化:服務(wù)器重啟后 Session 全部丟失,用戶需重新登錄,體驗(yàn)極差。
- 擴(kuò)展性差:無(wú)法通過(guò)增加服務(wù)器節(jié)點(diǎn)分擔(dān) Session 存儲(chǔ)壓力(每個(gè)節(jié)點(diǎn)仍需存儲(chǔ)全量 Session)。
二、Redis:分布式環(huán)境下的 Session 存儲(chǔ)方案
Redis 是一款 高性能的分布式內(nèi)存數(shù)據(jù)庫(kù),支持多種數(shù)據(jù)結(jié)構(gòu),通過(guò)網(wǎng)絡(luò)提供服務(wù),天生適合替代傳統(tǒng) Session 存儲(chǔ)。
1. Redis 的核心特性(為何適合存儲(chǔ) Session)
- 分布式訪問(wèn):所有應(yīng)用服務(wù)器(如 Tomcat 集群)可通過(guò)網(wǎng)絡(luò)訪問(wèn)同一 Redis 實(shí)例(或集群),實(shí)現(xiàn)數(shù)據(jù)共享。
- 高效存儲(chǔ):基于內(nèi)存操作,讀寫(xiě)性能極高(單機(jī) QPS 可達(dá) 10 萬(wàn) +),滿足高并發(fā)場(chǎng)景。
- 豐富數(shù)據(jù)結(jié)構(gòu):支持 String(字符串)、Hash(哈希)等結(jié)構(gòu),適配 Session 的鍵值對(duì)存儲(chǔ)需求。
- 原生過(guò)期機(jī)制:支持為 Key 設(shè)置過(guò)期時(shí)間,自動(dòng)清理無(wú)效 Session,無(wú)需手動(dòng)維護(hù)。
- 持久化能力:通過(guò) RDB(快照)或 AOF(日志)將數(shù)據(jù)持久化到磁盤(pán),服務(wù)器重啟后可恢復(fù),避免數(shù)據(jù)丟失。
2. Redis 存儲(chǔ) Session 的結(jié)構(gòu)設(shè)計(jì)
將 Session 數(shù)據(jù)遷移到 Redis 時(shí),需設(shè)計(jì)合理的 Key 和 Value 結(jié)構(gòu),確保唯一性、可讀性和高效性:
| 設(shè)計(jì)維度 | 具體實(shí)現(xiàn) | 示例 |
|---|---|---|
| Key 設(shè)計(jì) | 以sessionId或token(替代sessionId的唯一標(biāo)識(shí))為核心,添加業(yè)務(wù)前綴(便于管理和區(qū)分)。 | login:session:abc123(abc123為sessionId;login:session:為業(yè)務(wù)前綴) |
| Value 設(shè)計(jì) | 優(yōu)先使用Hash 結(jié)構(gòu)(適合存儲(chǔ)多字段的用戶信息,支持單獨(dú)修改某字段);簡(jiǎn)單場(chǎng)景可用 String(存儲(chǔ) JSON 字符串)。 | Hash 結(jié)構(gòu):userId → "1001"username → "張三"loginTime → "2025-11-08 10:00:00"expire → "1800"(30 分鐘,單位秒) |
| 過(guò)期設(shè)置 | 為 Key 設(shè)置與maxInactiveInterval一致的過(guò)期時(shí)間(如 30 分鐘),Redis 自動(dòng)刪除過(guò)期 Key。 | EXPIRE login:session:abc123 1800(1800 秒后過(guò)期) |
3. 工作流程(替代傳統(tǒng) Session 后)
- 用戶登錄:用戶提交賬號(hào)密碼,服務(wù)器驗(yàn)證通過(guò)后生成唯一token(替代sessionId),將用戶信息存入 Redis(Key 為login:session:token,Value 為 Hash 結(jié)構(gòu)),并設(shè)置過(guò)期時(shí)間。
- 客戶端存儲(chǔ):服務(wù)器將token返回給客戶端(通常存入 Cookie 或 LocalStorage),客戶端后續(xù)請(qǐng)求通過(guò)請(qǐng)求頭(如Authorization: Bearer token)攜帶token。
- 請(qǐng)求驗(yàn)證:應(yīng)用服務(wù)器(如 Tomcat)接收到請(qǐng)求后,從請(qǐng)求中提取token,通過(guò) Redis 查詢對(duì)應(yīng)的用戶信息:
- 若存在:延長(zhǎng) Key 的過(guò)期時(shí)間(如重置為 30 分鐘),允許訪問(wèn);
- 若不存在(過(guò)期或未登錄):攔截請(qǐng)求,返回 “未登錄” 提示。
- 用戶退出:刪除 Redis 中對(duì)應(yīng)的 Key(DEL login:session:token),實(shí)現(xiàn) “登出” 效果。
4. 優(yōu)勢(shì)(對(duì)比傳統(tǒng) Session)
- 分布式共享:所有應(yīng)用服務(wù)器通過(guò) Redis 訪問(wèn)同一套 Session 數(shù)據(jù),解決 “跨服務(wù)器登錄狀態(tài)失效” 問(wèn)題。
- 內(nèi)存擴(kuò)展:Redis 可獨(dú)立部署,支持集群(分片 + 哨兵),存儲(chǔ)容量可橫向擴(kuò)展(不受單個(gè)應(yīng)用服務(wù)器內(nèi)存限制)。
- 持久化保障:RDB/AOF 機(jī)制確保 Session 數(shù)據(jù)在 Redis 重啟后不丟失,用戶無(wú)需重復(fù)登錄。
- 高效過(guò)期管理:Redis 的過(guò)期 Key 清理機(jī)制(惰性刪除 + 定期刪除)比 Tomcat 的內(nèi)存掃描更高效,減少資源消耗。
三、傳統(tǒng) Session 與 Redis 存儲(chǔ) Session 的核心對(duì)比
| 維度 | 傳統(tǒng) Session(Tomcat 內(nèi)存) | Redis 存儲(chǔ) Session |
|---|---|---|
| 存儲(chǔ)位置 | 單個(gè)應(yīng)用服務(wù)器(如 Tomcat)的內(nèi)存中 | 獨(dú)立的 Redis 服務(wù)器(或集群)內(nèi)存中 |
| 數(shù)據(jù)結(jié)構(gòu) | 進(jìn)程內(nèi)的HttpSession對(duì)象(Map式鍵值對(duì)) | Redis 的 Key-Value 對(duì)(Key 為token,Value 為 Hash/JSON) |
| 訪問(wèn)范圍 | 僅當(dāng)前應(yīng)用服務(wù)器可訪問(wèn)(內(nèi)存隔離) | 所有應(yīng)用服務(wù)器通過(guò)網(wǎng)絡(luò)訪問(wèn)(分布式共享) |
| 生命周期管理 | 依賴應(yīng)用服務(wù)器(如 Tomcat 的SessionManager) | 依賴 Redis 的過(guò)期 Key 機(jī)制(自動(dòng)清理) |
| 持久化能力 | 無(wú)(服務(wù)器重啟后數(shù)據(jù)丟失) | 支持(RDB/AOF 持久化到磁盤(pán)) |
| 擴(kuò)展性 | 差(受單個(gè)服務(wù)器內(nèi)存限制,無(wú)法分布式擴(kuò)展) | 好(Redis 集群可橫向擴(kuò)展,支持海量 Session) |
| 高并發(fā)支持 | 弱(內(nèi)存占用高,清理效率低) | 強(qiáng)(內(nèi)存數(shù)據(jù)庫(kù),讀寫(xiě)性能優(yōu)異,支持高 QPS) |
四、為何用 Redis 替代傳統(tǒng) Session(以黑馬點(diǎn)評(píng)為例)
黑馬點(diǎn)評(píng)作為高并發(fā)的分布式電商項(xiàng)目,需解決以下核心問(wèn)題,而 Redis 恰好適配:
- 分布式部署需求:項(xiàng)目需部署多臺(tái)應(yīng)用服務(wù)器(Tomcat 集群),傳統(tǒng) Session 的 “內(nèi)存隔離” 會(huì)導(dǎo)致用戶登錄狀態(tài)混亂,Redis 實(shí)現(xiàn)跨服務(wù)器會(huì)話共享。
- 高并發(fā)場(chǎng)景:秒殺、促銷等場(chǎng)景下用戶請(qǐng)求量激增,Redis 的高性能(毫秒級(jí)響應(yīng))可支撐大量 Session 讀寫(xiě),避免傳統(tǒng) Session 的內(nèi)存瓶頸。
- 用戶體驗(yàn)保障:Redis 持久化確保服務(wù)器重啟后 Session 不丟失,用戶無(wú)需重復(fù)登錄;過(guò)期機(jī)制可靈活控制登錄有效期(如 “7 天內(nèi)免登錄”)。
- 業(yè)務(wù)擴(kuò)展:Redis 的 Hash 結(jié)構(gòu)便于存儲(chǔ)用戶多維度信息(如會(huì)員等級(jí)、優(yōu)惠券數(shù)量),后續(xù)業(yè)務(wù)擴(kuò)展時(shí)無(wú)需修改存儲(chǔ)結(jié)構(gòu),兼容性更強(qiáng)。
總結(jié)
傳統(tǒng) Session 是 “單機(jī)內(nèi)存級(jí)” 的狀態(tài)存儲(chǔ),依賴單個(gè)應(yīng)用服務(wù)器,適合簡(jiǎn)單單機(jī)場(chǎng)景;而 Redis 是 “分布式級(jí)” 的狀態(tài)存儲(chǔ),通過(guò)網(wǎng)絡(luò)共享數(shù)據(jù),支持高并發(fā)、高可用和彈性擴(kuò)展,是分布式項(xiàng)目(如黑馬點(diǎn)評(píng))中替代傳統(tǒng) Session 的最優(yōu)解。
其核心邏輯是:用獨(dú)立的分布式存儲(chǔ)打破 Session 與服務(wù)器的強(qiáng)綁定,解決分布式場(chǎng)景下的會(huì)話一致性問(wèn)題。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot前后端分離項(xiàng)目之打包、部署到服務(wù)器詳細(xì)圖文流程
作為后臺(tái)開(kāi)發(fā),項(xiàng)目打包部署是經(jīng)常性的操作,下面這篇文章主要給大家介紹了關(guān)于SpringBoot前后端分離項(xiàng)目之打包、部署到服務(wù)器的相關(guān)資料,文中通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12
使用mybatis-plus想要修改某字段為null問(wèn)題
這篇文章主要介紹了使用mybatis-plus想要修改某字段為null問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02
使用Java實(shí)現(xiàn)希爾排序算法的簡(jiǎn)單示例
這篇文章主要介紹了使用Java實(shí)現(xiàn)希爾排序算法的簡(jiǎn)單示例,希爾排序可以被看作是插入排序的一種更高效的改進(jìn)版本,需要的朋友可以參考下2016-05-05
Java通過(guò)Callable實(shí)現(xiàn)多線程
這篇文章主要介紹了Java通過(guò)Callable實(shí)現(xiàn)多線程,Callable的任務(wù)執(zhí)行后可返回值,運(yùn)行Callable任務(wù)可以拿到一個(gè)Future對(duì)象,Future表示異步計(jì)算的結(jié)果,它提供了檢查計(jì)算是否完成的方法,以等待計(jì)算的完成,并檢查計(jì)算的結(jié)果,需要的朋友可以參考下2023-10-10
在jmeter的beanshell中用java獲取系統(tǒng)當(dāng)前時(shí)間的簡(jiǎn)單實(shí)例
這篇文章介紹了在jmeter的beanshell中用java獲取系統(tǒng)當(dāng)前時(shí)間的簡(jiǎn)單實(shí)例,有需要的朋友可以參考一下2013-09-09

