這篇文章主要為大家介紹了關於利用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
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,可以做到session在不同web伺服器中的共享。 #########最後再次強調:######
HttpSession的實作被Spring Session替換,操作HttpSession等同於操作redis中的資料。
以上是如何利用Spring Session和redis對Session進行共享得的相關介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!