當前位置:
首頁 > 知識 > 分散式環境session共享

分散式環境session共享

關於Cookie和Session的功能與工作原理,在這裡我就不再敘述了,大家想要了解可以看一下我的上一篇博客,講的還是很細緻的。

但是之前講的Session是運行在一台伺服器上的,所有的訪問都會到達我們的唯一伺服器上,這樣我們可以根據客戶端傳來的sessionID,來獲取session,或在對應Session不存在的情況下(session 生命周期到了/用戶第一次登錄),創建一個新的Session;但是,如果我們在集群環境下,假設我們有兩台伺服器A,B,用戶的請求會由Nginx伺服器進行轉發(別的方案也是同理),用戶登錄時,Nginx將請求轉發至伺服器A上,A創建了新的session,並將SessionID返回給客戶端,用戶在瀏覽其他頁面時,客戶端驗證登錄狀態,Nginx將請求轉發至伺服器B,由於B上並沒有對應客戶端發來sessionId的session,所以會重新創建一個新的session,並且再將這個新的sessionID返回給客戶端,這樣,我們可以想像一下,用戶每一次操作都有1/2的概率進行再次的登錄,這樣不僅對用戶體驗特別差,還會讓伺服器上的session激增,加大伺服器的運行壓力。

為了解決集群環境下的seesion共享問題,共有4種解決方案:

1.粘性session

粘性session是指Ngnix每次都將同一用戶的所有請求轉發至同一台伺服器上,即將用戶與伺服器綁定。

2.伺服器session複製

即每次session發生變化時,創建或者修改,就廣播給所有集群中的伺服器,使所有的伺服器上的session相同。

3.session共享

緩存session,使用redis, memcached。

4.session持久化

將session存儲至資料庫中,像操作數據一樣才做session。

其實,最簡單的兩種方案,就是方案一和方案三,都不需要對session進行任何操作,只需要將Nginx和Tomcat上的配置文件修改一下即可。由於我們做集群,訪問量一定是比較大的了,對於第一種方案,如果某台伺服器發生故障,此伺服器上的所有用戶的session都會丟失,所以今天我們採用第三種解決方案。

感謝開源項目tomcat-redis-session-manager,感謝項目的發起者jcoleman。

此方案最簡單之處就在於我們無需修改項目,只需要修改Tomcat的context.xml配置文件即可,並且,redis伺服器同樣可以做分散式。

接下來,我們來講解一下如何配置tomcat,首先,講解一下注意事項,因為項目的原因,並沒能用maven來管理依賴的包,而在我配置的時候,很正常的發生了包版本間的衝突,從redis中取出的序列化後的session無法轉換為HttpSession,所以,大家做的時候一定要注意版本間的兼容問題。

把我使用的版本給大家做個參考吧,tomcat-redis-session-manager-1.1.jar,jedis-2.1.0.jar,commons-pool-1.6.jar

這三個包需放入 tomcat的安裝目錄下的lib文件夾下,IDE自帶的tomcat可以在配置中查看。

需注意的是,當redis的版本『過高』時,需要依賴commons-pool2.jar,(具體版本不寫)。

接下來,我們就講一下最核心的配置,配置context.xml文件(文件路徑workspace.metadata.me_tcat7conf,此處僅是myeclipse編輯器的路徑)

[html] view plain copy

  1. <Valve

    className="com.radiadesign.catalina.session.RedisSessionHandlerValve"

    />

  2. <Manager

    className="com.radiadesign.catalina.session.RedisSessionManager"
  3. host="127.0.0.1"
  4. port="9313"
  5. database="0"
  6. maxInactiveInterval="60"

    />

這個裡的class路徑具體看tomcat-redis-session-manager里的路徑。

可能你會遇到重啟tomcat配置文件會被還原的問題,那麼你還需要修改另一處的context.xml文件,workspaceServersMyEclipse Tomcat v7.0-config文件夾中的,修改內容同上。

接下來,給大家看一下配置完成後的結果:

分散式環境session共享

圖1為監聽到的redis伺服器的狀態,可以看到我們將session序列化後以sessionID為key存入了redis中,圖2可以看到是客戶端header中的cookie信息(若有疑問可以查看我上一篇的博客),圖三是我在redis客戶端get key為sessionID的記錄,可以驗證成功,我們配置是成功了的,因為使用的自己的電腦,配置有限,並沒有開幾個tomcat來測試,不過上述還是很有說服力的(線上已經測試過了)。

希望對你有幫助!

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

一些docker的技巧和秘訣
mybatis使用load data local infile實現導入數據到mysql資料庫

TAG:程序員小新人學習 |