spring boot 的session跨域共享

620

前言

如果你正在使用Java開發Web應用,想必你對HttpSession非常熟悉,但我們知道HpptSession默認使用內存來管理Session,如果將應用橫向擴展將會出現Session共享問題。Spring Session提供了一套創建和管理Servlet HttpSession的方案,以此來解決Session共享的問題,更爲重要的是在Spring Boot中使用它極其簡單。

Session共享的問題

HttpSession是通過Servlet容器創建和管理的,像Tomcat/Jetty都是保存在內存中的。如果我們將Web應用橫向擴展搭建成分佈式的集羣,然後利用LVS或Nginx做負載均衡,那麼來自同一用戶的Http請求將有可能被負載分發到兩個不同的實例中去,如何保證不同實例間Session共享成爲一個不得不解決的問題。

最簡單的解決方法就是把Session數據保存到內存以外的一個統一的地方,例如Memcached/Redis中。那麼問題又來了,如何替換掉Servlet容器創建和管理HttpSession的實現呢?

  1. 利用Servlet容器提供的插件功能,自定義HttpSession的創建和管理策略,並通過配置的方式替換掉默認的策略。不過這種方式有個缺點,就是需要耦合Tomcat/Jetty等Servlet容器的代碼。這方面其實早就有開源項目了,例如memcached-session-manager,以及tomcat-redis-session-manager。暫時都只支持Tomcat6/Tomcat7。

  2. 配置Nginx的負載均衡算法爲ip_hash,這樣每個請求按訪問IP的hash結果分配,這樣來自同一個IP的訪客固定訪問一個後端服務器,有效解決了動態網頁存在的Session共享問題

  3. 如果你使用Shiro管理Session,可以用Redis來實現Shiro 的SessionDao接口,這樣Session便歸Redis保管。

  4. 設計一個Filter,利用HttpServletRequestWrapper,實現自己的 getSession()方法,接管創建和管理Session數據的工作。Spring-Session就是通過這樣的思路實現的。

在Spring Boot中 集成 Spring Session

Spring Session 支持使用Redis、Mongo、JDBC、Hazelcast來存儲Session,這裏以Redis爲例。

  1. 引入Maven依賴(本示例使用dependencyManagement,如果你沒有使用它請添加<version>標籤)

         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-redis</artifactId>
             <version>${redis.version}</version>
            </dependency>
  2.      
         <dependency>
             <groupId>org.springframework.session</groupId>
             <artifactId>spring-session</artifactId>
             <version>${spring-session.version}</version>
         </dependency>
  3. 配置你的Spring Application,將你的application.properties加入以下配置。

    spring.session.store-type=redis

   @EnableConfigurationProperties與上述配置效果相同,找個地方放上去就好了




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章