叢集session一致性和同步問題
一. 何為session
使用者使用網站的服務,基本上需要瀏覽器和web伺服器進行多次互動,web伺服器如何知道哪些請求是來自哪個會話的?
具體方式為:在會話開始時,分配一個唯一的會話標識(sessionId),通過cookie把這個標識告訴瀏覽器,以後每次請求的時候,瀏覽器都會帶上這個會話標識來告訴web伺服器請求是屬於哪個會話的。如果遇到禁用cookie的情況,一般的做法就是把這個會話標識放到url的引數中。
二. 問題
因為會話資訊儲存在單機上,當我們的應用伺服器從一臺變成兩臺後,我們就會遇到session的問題了!
如下圖所示,當我們第一次訪問網站時請求落到了左邊的伺服器,那麼我的session就建立在左邊的伺服器上了,如果我們不做處理,就不能保證接下來的請求每次都落在同一邊的伺服器上了,這就是session問題。
三. 解決辦法:
1. session sticky
在web伺服器變成多臺後,如果我們可以保證同一個會話請求都能在同一個web伺服器上處理,那麼對於這個會話個體來說,和單機的情況是一樣的。這就需要負載均衡器能夠根據每次請求的會話標識來進行請求轉發。
有何問題:
① 如果有一臺web伺服器宕機或重啟,那麼這臺機器上的會話資料會丟失
② 負載均衡器變成了一個有狀態的結點,要儲存會話到具體web伺服器的對映,要消耗一定的記憶體。
2. session replication
web伺服器之間增加了會話資料的同步,通過同步就保證了不同web伺服器之間的session資料一致,一般的應用容器都支援這種方式。
問題:
① 只要session資料有變化,就需要將資料同步到其他機器上,會帶來一定的網路頻寬開銷
② 每臺web伺服器都要儲存所有的session資料,如果整個叢集session數很多的話,對記憶體資源消耗較大。
該方案不適合叢集機器較多的場景。
3. session資料集中儲存
把session資料集中儲存起來,然後不同的web伺服器從相同的地方來獲取session,儲存session資料的方式可以為資料庫,也可以使用其他分散式儲存系統。
問題:
① 獲取session存在延時和不穩定性,不過我們的通訊基本在內網,問題不大。
② 如果儲存session的機器或叢集發生問題,就會影響到應用。
當叢集規模較大時,session數較多時,該方案可以考慮。
4. cookie based
該方案通過cookie來傳遞session資料,即把session資料存在cookie中
問題:
① cookie有長度限制,這也就會限制session資料的長度
② 安全性,cookie的資料儲存在客戶端,這就存在安全性的問題,我們需要對寫入cookie的session資料做加密處理
③ 頻寬消耗, 客戶端每次都要帶著session過來,會消耗一定網路資源
④ 效能影響,每次http請求和響應都帶有session資料,對web伺服器來說,在同樣的處理情況下,響應的結果輸出越少,支援的併發請求就會越多。
綜上方案都是解決session問題的方案,對於大型網站來說,session sticky和session集中管理是比較好的方案。