首頁  >  文章  >  Java  >  如何利用Spring Session和redis對Session進行共享得的相關介紹

如何利用Spring Session和redis對Session進行共享得的相關介紹

巴扎黑
巴扎黑原創
2017-09-06 09:24:561746瀏覽

這篇文章主要為大家介紹了關於利用Spring、Session和redis對Session進行共享的相關資料,文中透過範例程式碼介紹的非常詳細,對大家的學習或工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。

前言

我們在建置完叢集環境後,不得不考慮的一個問題就是使用者存取產生的session如何處理。

session的處理有很多種方法,詳情請見轉載的上篇部落格:叢集/分散式環境下5種session處理策略

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

redis叢集做主從複製,利用redis資料庫的最終一致性,將session資訊存入redis。當應用程式伺服器發現session不在本機記憶體的時候,就去redis資料庫中查找,因為redis資料庫是獨立於應用程式伺服器的資料庫,所以可以做到session的共享和高可用。

不足:

1.redis需要記憶體較大,否則會出現使用者session從Cache中清除。

2.需要定期的刷新快取

初步結構如下:


#但這個結構仍然有問題,redis master是一個重要瓶頸,如果master崩潰的時候,但是redis不會主動的進行master切換,這時session服務中斷。 但是我們先做到這個結構,後面再進行最佳化修改。

Spring Boot提供了Spring Session來完成session共享。

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


先建立簡單的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"; 
 } 
}
簡單來說就是模擬一下權限控制,如果sessionId存在就存取主頁,否則就跳轉到登入頁面。

那要如何實現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(); 
 } 
}

這個設定類別有什麼用呢?

官方文檔:

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

也就是說,這個配置類別可以建立一個過濾器,這個過濾器支援Spring Session取代HttpSession發揮作用。

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 imple by Spring be backment by Spring Session. Redis.

@EnableRedisHttpSession註解會建立一個springSessionRepositoryFilter的bean物件去實作這個篩選器。過濾器負責取代HttpSession。

也就是說,

HttpSession不再發揮作用,而是透過過濾器使用redis直接操作Session。

在application.properties中加入redis的設定:

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

這樣,就完成了Session共享了。是不是很簡單?業務代碼甚至不需要一點點的修改。

驗證:

一開始redis資料庫是空的。

執行專案:

造訪頁面之後,可以在redis中看到session的資訊。

隨便登陸之後:

進入了main中。說明目前這個session中是存在sessionId的。

我們查看目前頁面的cookie。也就是說,這個cookie是存在sessionId的。


再運行一個新的項目,連接埠為8081。在原本的瀏覽器中直接開啟一個新的標籤頁,我們知道,這個時候cookie是共享的。訪問localhost:8081/main

我們直接存取新的專案成功了! !同一個cookie,可以做到session在不同web伺服器中的共享。 #########最後再次強調:######

HttpSession的實作被Spring Session替換,操作HttpSession等同於操作redis中的資料。

以上是如何利用Spring Session和redis對Session進行共享得的相關介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn