三、Nginx+Tomcat+Redis實現Session共享



這次繼續上次沒有解決的問題——如何解決多臺Apache服務器Session共享,實現單點登錄。

一、Redis簡介及下載安裝

作爲這次的主角,相信大家對redis應該都一定印象,redis是一款開源的高性能key-value數據庫,擁有豐富的鍵值儲存類型,並提供多種語言的API。

與一般數據庫不同,redis是使用內存作爲主存,而使用硬盤來實現數據持久化,而且redis是週期性的將數據寫到硬盤上。這就意味着一旦我們服務器出現斷電、重啓之類的情況,我們很可能會出現數據丟失的情況,所以不建議使用redis來存放關鍵的數據。當然,也正因爲redis讀寫數據都使用內存,所以它的速度是非常快的,很適合我們來存放一些臨時性的數據。

此外,redis能實現的作用很多,諸如隊列、緩存之類的,但我也還沒使用過,無法在這裏爲大家說明,但不影響我們今天的session共享功能。

首先我們先下載redis,這是windows版本的下載地址  https://github.com/ServiceStack/redis-windows

可以點擊右邊下載全部文件,但感覺沒必要,而且下載速度偏慢,建議進入downloads裏面下載我們所需的redis包即可。

redis在windows下是免安裝的,下載完成後,解壓,將文件夾複製到自己某個盤中就好了。解壓後是這個樣子的。

一開始redis是默認不需要密碼,如果想要設置密碼,可以進入redis.windows.conf文件下找到requirepass,刪除前面的#號,在其後面便可以設置密碼,我這裏設成了123456。

下面我們打開redis。首先打開cmd,進入我們redis目錄下,輸入redis-server.exe redis.windows.conf。出現下面界面,則打開成功。

另外和別的數據庫一樣,我們需要安裝一個輔助的可視化工具Redis Desktop Manager,這是下載地址:http://redisdesktop.com/download

我們下載windows版本,安裝完成後,還沒有任何連接對象,那就讓我們給它添加一個。點擊下方的connect to redis server,出現個彈出框。然後Name我們可以隨便輸,Host添我們redis服務器的ip地址,本地可以直接填寫localhost,端口默認爲6379,Auth就是密碼,不是必填項,如果沒設置密碼可不填,點擊OK,建立完成。

至此,準備工作都已經完成,下面開始我們的spring與redis的整合之旅。

二、Spring與Redis的整合之旅

我本人使用的是傳統的SSH框架。Spring本身有提供對redis的支持,就是spring-session,我們只需將這個在pom.xml添加如下代碼,maven便會自己下載所需的jar包及依賴包。

<dependency>

     <groupId>org.springframework.session</groupId>

     <artifactId>spring-session-data-redis</artifactId>

     <version>1.1.1.RELEASE</version>

     <type>pom</type>

</dependency>

隨後我們在resources文件夾中新建一個redis.properties,往裏面添加如下內容。

#host address

redis_hostName = localhost

#port

redis_port = 6379

#password

redis_password = 123456

#time_out

redis_timeout = 20000

 

再新建一個spring-redis.xml,往裏面添加我們redis相關的配置。其中maxInactiveIntervalInSeconds是設置session有效時間,以秒爲單位,但實際上無論怎麼設,session真實有效時間還是會比我們設置的稍長一些。

<?xml version="1.0"encoding="UTF-8"?>

<beansxmlns="http://www.springframework.org/schema/beans"

      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xsi:schemaLocation="http://www.springframework.org/schema/beans

      http://www.springframework.org/schema/beans/spring-beans.xsd">

   <!-- session設置 -->

   <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">

       <property name="maxInactiveIntervalInSeconds"value="3600"></property>

   </bean>

   <!-- redis連接池 -->

   <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"/>

   <!-- redis連接工廠 -->

   <bean id="connectionFactory"class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">

       <property name="hostName"value="${redis_hostName}"/>

       <property name="port" value="${redis_port}"/>

       <property name="password"value="${redis_password}"/>

       <property name="timeout"value="${redis_timeout}"/>

       <property name="poolConfig"ref="poolConfig"></property>

   </bean>

</beans>

添加完成後,別忘了還要在spring.xml和web.xml引入我們新添加的文件,引入代碼這裏就不給出了。

最後我們還需要在web.xml中加入spring的session過濾器,我個人理解這個過濾器的作用是告訴spring來接管對session管理與創建工作。

<!--session過濾器-->

 <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>

 </filter-mapping>

完成這一步以後,我們對redis的集成就完成了,接下來我們測試一下。

三、Session共享測試

爲了完成測試,我先在UserAction中添加了一個簡單方法,第一步是檢查登陸者的信息,第二步是保存登錄用戶的Session信息。需要注意的是如果要往redis中存入對象,則需要改對象序列化才能存入。

 

現在已經完成測試前的全部工作了,開始測試吧。

啓動tomcat1,在瀏覽器中輸入lenovo.cloudtest.com,進入我們的登錄頁面,登錄頁面代碼就不貼出了,就是ajax提交而已。輸入我們的用戶名和密碼。登錄。看到我們登錄成功了,首頁能成功顯示我們的用戶名。

再看看我們redis服務器,可以看到裏面已經添加了一些數據,有些session是spring自己添加的,具體什麼意思我也不是很清楚,但我們找一下,就可以找到我們剛剛添加的session。其中右上角的TIL是我們session剩餘有效時間。

那麼這session是否能被共享呢? 讓我們老規矩,複製tomcat1的項目,到tomcat2中去,修改個別字以區分頁面。

啓動項目,直接在瀏覽器中輸入項目路徑,輸入密碼。可以看到沒報任何空指針錯誤,直接就進入了個登錄頁面。共享成功。

 

隨後打開我們上次配置好的nginx,進入登錄界面,進行登錄步驟,我們就可以看到我們可能在tomcat1登錄,進入tomcat2的項目當中,當然可能反之,刷新頁面,會看見兩個tomcat的頁面在間隔得顯示,測試成功。

再補充個上次漏掉的,這時我們可以關閉其中一個服務器,我關了tomcat1,再多次刷新頁面,會發現接下來出現的都是tomcat2的頁面,這時必然的,但是時而快時而慢。這其中原因是當nginx將請求轉發到tomcat2時,服務器當然能做出立即性響應,但要是轉到了tomcat1,就會出現一段長達1分多鐘的等待響應過程,這顯然我們是不能接受的。對此我們需要對ngin配置進行寫修改。在這裏先介紹幾個標籤。

·        proxy_connect_timeout:與服務器連接的超時時間,默認60s

·        fail_timeout:當該時間內服務器沒響應,則認爲服務器失效,默認10s

·        max_fails:允許連接失敗次數,默認爲1

這裏我們所需等待時間 = proxy_connect_timeout+ fail_timeout*max_fails,所以我如下配置只需等待3秒,nginx便會將請求轉給tomcat2,還是在能接受範圍內的。

四、小結

該說的在前文也說了,總而言之,spring已經爲我們的session共享提供了很好的支持,我們只需好好利用它就好了。

 

 

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