分佈式架構下,session共享有什麼方案麼?

低調的牛肉


分佈式架構下的session共享,也可以稱作分佈式session一致性;關於這個問題,和大家說一說解決方案(如果有其他的方案,可以留言討論)。


session的作用

如果大家做過web應用開發的話,應該對session比較熟悉;服務器會為每個用戶創建一個會話,存儲用戶的相關信息,以便在後面的請求中,可以夠定位到同一個上下文。

例如用戶在登錄之後,再進行頁面跳轉的時候,存儲在session中的信息會一直保持,如果用戶還沒有session,那麼服務器會創建一個session對象,直到會話過期或主動放棄後(退出),服務器才會把session終止掉。

分佈式架構中的session問題

在N年前,那個都是單個服務器的年代,session直接保存在服務器中,是一點問題沒有的,而且實現起來很容易。

但是隨著分佈式架構的流行,單個服務器已經不能滿足系統的需要了,通常都會把系統部署在多臺服務器上,通過負載均衡把請求分發到其中的一臺服務器上,這樣很可能同一個用戶的請求被分發到不同的服務器上,因為session是保存在服務器上的,那麼很有可能第一次請求訪問的A服務器,創建了session,但是第二次訪問到了B服務器,這時就會出現取不到session的情況。

於是,分佈式架構中,session共享就成了一個很大的問題。

解決方案

  1. 不要有session:大家可能覺得我說了句廢話,但是確實在某些場景下,是可以沒有session的,其實在很多接口類系統當中,都提倡【API無狀態服務】;也就是每一次的接口訪問,都不依賴於session、不依賴於前一次的接口訪問;
  2. 存入cookie中:將session存儲到cookie中,但是缺點也很明顯,例如每次請求都得帶著session,數據存儲在客戶端本地,是有風險的;
  3. session同步:對個服務器之間同步session,這樣可以保證每個服務器上都有全部的session信息,不過當服務器數量比較多的時候,同步是會有延遲甚至同步失敗;
  4. 使用Nginx(或其他複雜均衡軟硬件)中的ip綁定策略,同一個ip只能在指定的同一個機器訪問,但是這樣做風險也比較大,而且也是去了負載均衡的意義;
  5. 我們現在的系統會把session放到Redis中存儲,雖然架構上變得複雜,並且需要多訪問一次Redis,但是這種方案帶來的好處也是很大的:實現session共享,可以水平擴展(增加Redis服務器),服務器重啟session不丟失(不過也要注意session在Redis中的刷新/失效機制),不僅可以跨服務器session共享,甚至可以跨平臺(例如網頁端和APP端)。

希望我的回答,能夠幫助到你!我將持續分享Java開發、架構設計、程序員職業發展等方面的見解,希望能得到你的關注。


分享到:


相關文章: