分布式下Session一致性問題
一、Session一致性問題
1.1 什麽是Session
用戶使用網站的服務,基本上需要瀏覽器和web服務器進行多次交互,web服務器如何知道哪些請求是來自哪個會話的?
具體方式為:在會話開始時,分配一個唯一的會話標識(sessionId),通過cookie把這個標識告訴瀏覽器,以後每次請求的時候,瀏覽器都會帶上這個會話標識來告訴web服務器請求是屬於哪個會話的。如果遇到禁用cookie的情況,一般的做法就是把這個會話標識放到url的參數中。
1.2 什麽是Session一致性問題
因為會話信息保存在單機上,當我們的應用服務器從一臺變成兩臺後,我們就會遇到session的問題了!
如下圖所示,當我們第一次訪問網站時請求落到了左邊的服務器,那麽我的session就創建在左邊的服務器上了,如果我們不做處理,就不能保證接下來的請求每次都落在同一邊的服務器上了,這就是session問題。
二、解決方案
start nginx
nginx -s stop
nginx -s reload
以下方案都是解決session問題的方案,對於大型網站來說,session sticky和session集中管理是比較好的方案。
2.1 session sticky
session sticky
http://blog.csdn.net/tomcat_baby/article/details/52787679
http://blog.csdn.net/yangbutao/article/details/12971037
在web服務器變成多臺後,如果我們可以保證同一個會話請求都能在同一個web服務器上處理,那麽對於這個會話個體來說,和單機的情況是一樣的。這就需要負載均衡器能夠根據每次請求的會話標識來進行請求轉發。
有何問題:
① 如果有一臺web服務器宕機或重啟,那麽這臺機器上的會話數據會丟失
② 負載均衡器變成了一個有狀態的結點,要保存會話到具體web服務器的映射,要消耗一定的內存。
實現:
基於nginx的ip_hash策略來做負載均衡,根據ip做hash計算,同一個ip的請求始終會定位到同一臺tomcat,這樣做的好處是對應用無侵入,可以水平擴展
2.2 session replication
web服務器之間增加了會話數據的同步,通過同步就保證了不同web服務器之間的session數據一致,一般的應用容器都支持這種方式。
問題:
① 只要session數據有變化,就需要將數據同步到其他機器上,會帶來一定的網絡帶寬開銷
② 每臺web服務器都要保存所有的session數據,如果整個集群session數很多的話,對內存資源消耗較大。
該方案不適合集群機器較多的場景。
實現:
服務器Session復制,Tomcat服務器創建Session後,會通過組播方式把session發送到組播
2.3 session數據集中存儲
把session數據集中存儲起來,然後不同的web服務器從相同的地方來獲取session,存儲session數據的方式可以為數據庫,也可以使用其他分布式存儲系統。
問題:
① 獲取session存在延時和不穩定性,不過我們的通信基本在內網,問題不大。
② 如果存儲session的機器或集群發生問題,就會影響到應用。
當集群規模較大時,session數較多時,該方案可以考慮。
實現:Session不由tomcat管理,而是統一放到一個地方集中式管理,讀取和寫入Session都依賴第三方軟件。例如redis,mongodb,mysql等
2.4 cookie based
該方案通過cookie來傳遞session數據,即把session數據存在cookie中
問題:
① cookie有長度限制,這也就會限制session數據的長度
② 安全性,cookie的數據保存在客戶端,這就存在安全性的問題,我們需要對寫入cookie的session數據做加密處理
③ 帶寬消耗, 客戶端每次都要帶著session過來,會消耗一定網絡資源
④ 性能影響,每次http請求和響應都帶有session數據,對web服務器來說,在同樣的處理情況下,響應的結果輸出越少,支持的並發請求就會越多。
三、參考:
- session一致性架構設計實踐
- 集群session一致性和同步問題
分布式下Session一致性問題