Spring Session實戰-傳統單體應用叢集部署解決方案

NO IMAGE
1 Star2 Stars3 Stars4 Stars5 Stars 給文章打分!
Loading...

場景值1

一個維護了幾百年的單體老專案,突然就火起來了,訪問人數突然暴增,伺服器資源告急,擔心一下駕崩,老闆一個電話過來跟你說:“![email protected]!#!!¥@!¥1¥@!”,然後你得大半夜從睡夢中醒來屁顛屁顛的整伺服器。

場景值2

下班了,準備發完版本就回去。等等,老闆還在演示,又不能中斷伺服器去部署應用。一不小心,一個鐘過去了,還沒結束,你得等啊等啊,終於可以釋出了。然後你利索的./shutdown下去,程式碼啪啦啪啦的上傳完,準備啟動了,盯著啟動日誌,天哪,怎麼log卡住不動了。然後客服機立馬就有人來找你麻煩了。

更多場景值,此處省略好多 …

Spring Session是什麼

  • Spring Session提供了一個管理使用者會話資訊的API和實現。它還提供透明的整合:

    • HttpSession – 允許以應用程式容器(即Tomcat)中立的方式替換HttpSession。其他功能包括:
    • 群集會話 – Spring Session使得支援群集會話變得輕而易舉,而不會受限於特定於應用程式容器的解決方案。
    • 多個瀏覽器會話 – 春季會話支援在單個瀏覽器例項中管理多個使用者的會話(即與Google類似的多個經過身份驗證的帳戶)。
    • RESTful API – Spring Session允許在標頭檔案中提供會話識別符號以使用RESTful API
  • WebSocket – 提供HttpSession在接收WebSocket訊息時保持活動狀態的能力

白話:spring session抽象了一套API,並基於這套API對servlet容器提供的session進行無侵入整合,比如使用redis進行session管理,實現所謂的分散式session。

Spring Session座標

以Maven做為依賴管理,基於redis的Spring Session實現

<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
    <version>1.0.2.RELEASE</version>
    <type>pom</type>
</dependency>

Spring Session怎麼使用

Spring session對主流的Servlet容器如Tomcat提供透明的整合HttpSession。這意味著開發人員使用HttpSession可藉助Spring Session支援的實現切換實現。

使用redis

Redis有多種客戶端實現,常用的有Jedis和Lettuce。具體差別讀者可另行翻閱其他資料。本文以Jedis為例。

  • 基於java配置

    • Sring Java配置

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

      說明:預設的JedisConnectionFactory()構造方法是連結localhost:6379無密碼的redis-server,實際生產環境可按需選擇合適的構造方法。

    • Java Servlet容器初始化
      Spring配置建立了一個名為springSessionRepositoryFilter實現的Spring Bean Filter。該springSessionRepositoryFilterbean負責HttpSession用Spring Session支援的自定義實現來替換它。

      為了讓我們Filter發揮它的魔力,Spring需要載入Config.java。最後,我們需要確保我們的Servlet容器(即Tomcat)使用我們springSessionRepositoryFilter的每個請求。
      幸運的是,Spring Session提供了一個AbstractHttpSessionApplicationInitializer,繼承它,把配置傳入進去即可,程式碼如下:

      public class Initializer extends AbstractHttpSessionApplicationInitializer {
          publicInitializer() {
              super(Config.class);
          }
      }
  • 基於xml配置

    • bean 配置

      <context:annotation-config />
      
      <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration" />
      
      <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" 
          p:host-name="${redis.host}" 
          p:port="${redis.port}" 
          p:password="${redis.password}" />

      基於xml的配置也相當簡單,這裡注意一下p名稱空間,新增引用xmlns:p="http://www.springframework.org/schema/p"

    • web.xml 配置 filter

      <filter>
          <filter-name>springSessionRepositoryFilter</filter-name>
          <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
      </filter>
      <filter-mapping>
          <filter-name>springSessionRepositoryFilter</filter-name>
          <url-pattern>/*</url-pattern>
          <dispatcher>REQUEST</dispatcher>
          <dispatcher>ERROR</dispatcher>
      </filter-mapping>

到此為止,應用已經整合了Spring Session,感覺不要太爽了!

測試Spring Session

  • 把瀏覽器本地快取先清一清
  • 輸入訪問地址 http://localhost:8080/login

注意看中間的紅色部分,沒有了原來的jessionid,但是新增了 session。這是實現分散式session的關鍵。

  • 登入系統,訪問到主頁
  • 關閉伺服器,重啟
  • 重新整理頁面,咦?不需要重新登入?

叢集部署(負載均衡)

這裡不是本文重點,就不展開細說了,由於上面已經解決了應用伺服器session共享的問題,所以叢集實現也是非常的簡便,通過nginx反向代理到2個部署到應用的tomcat即可。

相關文章

開發語言 最新文章