redis實現(xiàn)session共享的方法
引言
大廠很多項目都是部署到多臺服務(wù)器上,這些服務(wù)器在各個地區(qū)都存在,當(dāng)我們訪問服務(wù)時雖然執(zhí)行的是同一個服務(wù),但是可能是不同服務(wù)器運(yùn)行的;
在我學(xué)習(xí)項目時遇到這樣一個登錄情景,假設(shè)有如下三臺服務(wù)器(如圖),就使用session存放用戶的登錄信息,通過該信息可以判斷用戶是否登錄:
假設(shè)本次登錄是通過服務(wù)器01執(zhí)行的,那么這次的登錄session信息就存放到了內(nèi)存01中;但是當(dāng)我再次訪問時卻是服務(wù)器02執(zhí)行操作,而登錄session信息卻在內(nèi)存01中,服務(wù)器02無法獲取,所以它就會判斷我沒有登錄,返回錯誤的信息…
我們想要實現(xiàn)的就是通過一臺服務(wù)器登錄所生成的session可以和其他服務(wù)器共享,那么該如何實現(xiàn)?
解決方法 思路就是既然這幾個服務(wù)器自己的內(nèi)存不能共享,那么只要有一個共享空間供這幾個服務(wù)器共同訪問不就可以了(如圖);
首先想到的應(yīng)該就是數(shù)據(jù)庫,只要這些服務(wù)器集群共享一個數(shù)據(jù)庫,并把生成的session信息存放到數(shù)據(jù)庫中不就可以了,這樣大家都可以訪問;數(shù)據(jù)庫有關(guān)系型和非關(guān)系型(NoSql):
- 關(guān)系型數(shù)據(jù)庫:Mysql等
- 非關(guān)系型數(shù)據(jù)庫:Redis(K/V數(shù)據(jù)庫)等
這里其實選擇非關(guān)系型數(shù)據(jù)庫最好,因為Redis基于內(nèi)存,讀寫性能高,很適合這種用戶信息頻繁讀取的情況;
還可以通過文件服務(wù)器實現(xiàn),這里就不介紹了;
還有一種方法,可以通過nginx的iphash實現(xiàn),該方法非常簡單,但是思路和上面兩種不同,原理就是同一個ip的所有請求都會被nginx進(jìn)行iphash進(jìn)行計算,將結(jié)果綁定到指定服務(wù)器,之后這個請求都會訪問到該服務(wù)器中。
但是這樣就有一些問題,首先就算負(fù)載均衡就沒有太大意義了,如果綁定的服務(wù)器掛了,那么iphash也就失效了;又或者你的請求被其他服務(wù)分發(fā)而未走nginx服務(wù),那么iphash同樣不生效;所以謹(jǐn)慎使用;
下面我就簡單通過代碼模擬一下如何通過redis配置輕松實現(xiàn)session共享
案例介紹
這里有一個用戶管理項目,在登錄時登錄邏輯代碼會記錄下來登錄用戶的session信息:
然后同時開啟了該項目的兩個服務(wù):localhost:8080和localhost:8082(可以當(dāng)作兩臺不同服務(wù)器上運(yùn)行的項目)
開啟服務(wù)后可以訪問對應(yīng)的接口文檔:
-----------------------------------分割線-------------------------------------------
該服務(wù)都有以下兩個接口:(以下測試是在同一個服務(wù)中測試的)
登錄接口:記錄登錄用戶session信息
登錄測試:
獲取當(dāng)前用戶信息接口:通過登錄session獲取當(dāng)前用戶信息
獲取當(dāng)前登錄用戶信息測試:
因為現(xiàn)在這是兩個服務(wù),所以肯定實現(xiàn)不了共享session的,就算在8080端口的服務(wù)登錄了,也無法在8082端口的服務(wù)獲取到當(dāng)前用戶信息;(再次強(qiáng)調(diào):上面測試可以獲取到當(dāng)前用戶信息是因為在同一個服務(wù)中測試的,同一個服務(wù)session存放到他自己的內(nèi)存中當(dāng)然可以自己訪問了)
具體操作
下面就通過redis配置實現(xiàn)共享session:
首先要下載redis,下載網(wǎng)上找教程;這里我直接用的在服務(wù)器上通過docker創(chuàng)建的redis容器(簡單好用,強(qiáng)烈推薦):
通過可視化工具可以連接一下:
這樣redis就配置好了,下面在項目代碼中配置redis:
在項目中引入redis依賴和spring-session配置依賴(自動將 session 存儲到 redis 中):
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>2.6.4</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.session/spring-session-data-redis --> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> <version>2.6.3</version> </dependency>
在application.yml文件中配置連接redis和session相關(guān)配置:
spring: # session配置 session: timeout: 86400 # 設(shè)置session失效時間 store-type: redis # 修改spring-session存儲配置,默認(rèn)存儲到服務(wù)器內(nèi)存中,現(xiàn)在設(shè)置存到redis中(關(guān)鍵) # redis配置 redis: port: 8081 # redis的端口號(這里是我的redis容器在docker中對應(yīng)的端口號) host: xx.xxx.xxx.xxx # 我的云服務(wù)器ip database: 0 # 設(shè)置存入redis的哪一個庫(默認(rèn)是0)
其實關(guān)鍵配置就一個: store-type: redis,只要配置了這個,那么代碼中session就會存放到redis中而不是自己的內(nèi)存中;
接下來就可以測試了:
調(diào)用登錄接口,生成用戶session信息,查看redis:
可以看到用戶登錄session已經(jīng)存放到redis中了,這樣我在8080端口登錄,在8082也可以獲取到登錄的session信息:
登錄:
獲取信息:
這樣就通過redis實現(xiàn)session共享了;
需要注意:引入redis和spring-redis依賴版本需要接近;
到此這篇關(guān)于redis實現(xiàn)session共享的方法的文章就介紹到這了,更多相關(guān)redis session共享內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot +redis 實現(xiàn)點贊、瀏覽、收藏、評論等數(shù)量的增減操作
這篇文章主要介紹了springboot +redis 實現(xiàn)點贊、瀏覽、收藏、評論等數(shù)量的增減操作,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09Redis和數(shù)據(jù)庫 數(shù)據(jù)同步問題的解決
這篇文章主要介紹了Redis和數(shù)據(jù)庫 數(shù)據(jù)同步問題的解決操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01