溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

利用Spring Session和redis對(duì)Session進(jìn)行共享詳解

發(fā)布時(shí)間:2020-09-27 21:42:12 來(lái)源:腳本之家 閱讀:207 作者:a60782885 欄目:編程語(yǔ)言

前言

我們?cè)诖罱ㄍ昙涵h(huán)境后,不得不考慮的一個(gè)問(wèn)題就是用戶訪問(wèn)產(chǎn)生的session如何處理。

session的處理有很多種方法,詳情見(jiàn)轉(zhuǎn)載的上篇博客:集群/分布式環(huán)境下5種session處理策略

在這里我們討論其中的第三種方法:session共享。

redis集群做主從復(fù)制,利用redis數(shù)據(jù)庫(kù)的最終一致性,將session信息存入redis中。當(dāng)應(yīng)用服務(wù)器發(fā)現(xiàn)session不在本機(jī)內(nèi)存的時(shí)候,就去redis數(shù)據(jù)庫(kù)中查找,因?yàn)閞edis數(shù)據(jù)庫(kù)是獨(dú)立于應(yīng)用服務(wù)器的數(shù)據(jù)庫(kù),所以可以做到session的共享和高可用。

不足:

1.redis需要內(nèi)存較大,否則會(huì)出現(xiàn)用戶session從Cache中被清除。

2.需要定期的刷新緩存

初步結(jié)構(gòu)如下:

利用Spring Session和redis對(duì)Session進(jìn)行共享詳解

但是這個(gè)結(jié)構(gòu)仍然存在問(wèn)題,redis master是一個(gè)重要瓶頸,如果master崩潰的時(shí)候,但是redis不會(huì)主動(dòng)的進(jìn)行master切換,這時(shí)session服務(wù)中斷。

但是我們先做到這個(gè)結(jié)構(gòu),后面再進(jìn)行優(yōu)化修改。

Spring Boot提供了Spring Session來(lái)完成session共享。

官方文檔:http://docs.spring.io/spring-session/docs/current/reference/html5/guides/boot.html#boot-sample

首先創(chuàng)建簡(jiǎn)單的Controller:

@Controller 
public class UserController { 
 
 @RequestMapping(value="/main", method=RequestMethod.GET) 
 public String main(HttpServletRequest request) { 
 HttpSession session = request.getSession(); 
 String sessionId = (String) session.getAttribute("sessionId"); 
 if (null != sessionId) { // sessionId不為空 
 System.out.println("main sessionId:" + sessionId); 
 return "main"; 
 } else { // sessionId為空 
 return "redirect:/login"; 
 } 
 } 
 
 
 @RequestMapping(value="/login", method=RequestMethod.GET) 
 public String login() { 
 return "login"; 
 } 
 
 @RequestMapping(value="/doLogin", method=RequestMethod.POST) 
 public String doLogin(HttpServletRequest request) { 
 System.out.println("I do real login here"); 
 HttpSession session = request.getSession(); 
 String sessionId = UUID.randomUUID().toString(); 
 session.setAttribute("sessionId", sessionId); 
 System.out.println("login sessionId:" + sessionId); 
 return "redirect:/main"; 
 } 
} 

簡(jiǎn)單來(lái)說(shuō)就是模擬一下權(quán)限控制,如果sessionId存在就訪問(wèn)主頁(yè),否則就跳轉(zhuǎn)到登錄頁(yè)面。

那么如何實(shí)現(xiàn)session共享呢?

加入以下依賴:

<!-- spring session --> 
<dependency> 
 <groupId>org.springframework.session</groupId> 
 <artifactId>spring-session</artifactId> 
 <version>1.3.0.RELEASE</version> 
</dependency> 
<!-- redis --> 
<dependency> 
 <groupId>org.springframework.boot</groupId> 
 <artifactId>spring-boot-starter-redis</artifactId> 
</dependency> 

增加配置類:

@EnableRedisHttpSession 
public class HttpSessionConfig { 
 @Bean 
 public JedisConnectionFactory connectionFactory() { 
 return new JedisConnectionFactory(); 
 } 
} 

這個(gè)配置類有什么用呢?

官方文檔:

The Spring configuration is responsible for creating a Servlet Filter that replaces the HttpSession implementation with an implementation backed by Spring Session. 

也就是說(shuō),這個(gè)配置類可以創(chuàng)建一個(gè)過(guò)濾器,這個(gè)過(guò)濾器支持Spring Session代替HttpSession發(fā)揮作用。

The @EnableRedisHttpSession annotation creates a Spring Bean with the name of springSessionRepositoryFilter that implements Filter. The filter is what is in charge of replacing the HttpSession implementation to be backed by Spring Session. In this instance Spring Session is backed by Redis.

@EnableRedisHttpSession注解會(huì)創(chuàng)建一個(gè)springSessionRepositoryFilter的bean對(duì)象去實(shí)現(xiàn)這個(gè)過(guò)濾器。過(guò)濾器負(fù)責(zé)代替HttpSession。

也就是說(shuō),HttpSession不再發(fā)揮作用,而是通過(guò)過(guò)濾器使用redis直接操作Session。

在application.properties中添加redis的配置:

spring.redis.host=localhost 
spring.redis.password= 
spring.redis.port=6379 

這樣,就完成了Session共享了。是不是很簡(jiǎn)單?業(yè)務(wù)代碼甚至不需要一點(diǎn)點(diǎn)的修改。

驗(yàn)證:

利用Spring Session和redis對(duì)Session進(jìn)行共享詳解

一開(kāi)始redis數(shù)據(jù)庫(kù)是空的。

運(yùn)行項(xiàng)目:

利用Spring Session和redis對(duì)Session進(jìn)行共享詳解

訪問(wèn)頁(yè)面之后,可以在redis中看到session的信息。

隨便登陸之后:

利用Spring Session和redis對(duì)Session進(jìn)行共享詳解

進(jìn)入到了main中。說(shuō)明當(dāng)前這個(gè)session中是存在sessionId的。

我們查看當(dāng)前頁(yè)面的cookie。也就是說(shuō),這個(gè)cookie是存在sessionId的。

利用Spring Session和redis對(duì)Session進(jìn)行共享詳解

再運(yùn)行一個(gè)新的項(xiàng)目,端口為8081。在原本的瀏覽器中直接打開(kāi)一個(gè)新的標(biāo)簽頁(yè),我們知道,這個(gè)時(shí)候cookie是共享的。訪問(wèn)localhost:8081/main

利用Spring Session和redis對(duì)Session進(jìn)行共享詳解

我們直接訪問(wèn)新的項(xiàng)目成功了??!同一個(gè)cookie,可以做到session在不同web服務(wù)器中的共享。

最后再次強(qiáng)調(diào):

HttpSession的實(shí)現(xiàn)被Spring Session替換,操作HttpSession等同于操作redis中的數(shù)據(jù)。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)億速云的支持。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI