1. 程式人生 > >解決應用伺服器叢集的Session問題

解決應用伺服器叢集的Session問題

使用者使用網站的服務,基本上需要瀏覽器與Web伺服器的多次互動。HTTP協議本身是無狀態的,需要基於HTTP協議支援會話狀態(Session State)的機制。而這樣的機制應該可以使Web伺服器從多次單獨的HTTP請求中看到“會話”,也就是知道請求是來自哪個會話的。

具體實現方式為:在會話開始時,分配一個唯一的會話標識(SessionId),通過Cookie把這個標識告訴伺服器,以後每次請求的時候,瀏覽器都會帶上這個會話標識來告訴Web伺服器請求是屬於哪個會話的。在Web伺服器上,各個會話有獨立的儲存,儲存不同會話的資訊。如果遇到禁用Cookie的情況,一般的做法就是把這個會話標識放到URL的引數中。


單臺應用伺服器

當一個帶有會話標識的HTTP請求到了Web伺服器後,需要在HTTP請求的處理過程中找到對應的會話資料(Session)。而問題在於會話資料是需要儲存在單機上的

在面對應用伺服器叢集時,如果我第一次訪問網站時請求通過負載均衡裝置落到了伺服器A,那麼我的Session就建立在伺服器A上了,如果我們不做處理,就不能保證接下來的請求每次都落在伺服器A上了。


應用伺服器叢集

1. Session Sticky

使負載均衡器能夠根據每次請求的會話標識來進行請求轉發。
需要在負載均衡伺服器上儲存會話到具體Web伺服器的對映。


Session Sticky

這種方法非常簡單,但是有以下幾個問題:

1.如果有一臺Web伺服器宕機或者重啟,那麼這臺機器上的會話資料會丟失。如果會話中有登陸狀態資訊,那麼使用者就要重新登入了。

2.會話標識是應用程式的資訊,負載均衡伺服器要將同一個會話的請求都儲存到一個Web伺服器上的話需要進行應用層(OSI模型第7層)的解析,這個開銷比第4層(傳輸層)的交換大。

3.負載均衡器變成了有狀態的節點,要儲存會話到Web伺服器的對映,比無狀態節點記憶體消耗更大,容災會更麻煩。

2.Session Replication

Web伺服器之間增加了會話資料的同步,應用伺服器叢集中的每一臺伺服器上都有一份會話資料。


Session Replication

但是也帶來了一些問題:

1.同步Session資料造成了網路頻寬的開銷。只要Session資料有變化就需要同步,機器數越多,同步帶來的網路頻寬開銷越大。

2.每臺Web伺服器都儲存所有額Session資料,在很多人同時訪問網站的時候,每臺機器用於儲存Session資料的內容佔用會很嚴重。

3.Session資料集中儲存

不同的伺服器從同樣的地方來獲取Session。會話請求經過負載均衡伺服器後,不會被固定在同樣的Web伺服器上,而是放在了一個集中儲存的地方。Web伺服器使用Session資料時,也是從這個集中儲存Session資料的地方來讀取。


Session資料集中儲存

這個方案解決了第一種方案的記憶體問題,也第二種方案佔用網路頻寬的情況要好。但是依然存在一些問題:

1.讀寫Session資料引入了網路操作,相對於本機的資料讀取來說,問題在於存在時延和不穩定性。
2.如果集中儲存Session的機器或者叢集有問題,就會影響我們的應用。

4.Cookie Based

把Session資料放在Cookie中,在Web伺服器上從Cookie中生成對應的Session資料。


Cookie Based


這個方案不會依賴外部儲存系統,也就不存在從外部系統獲取、寫入資料的網路時延和不穩定性了。
不過依然存在不足:

1.Cookie長度的限制。Cookie長度會限制Session資料的長度。
2.安全性。Session資料是服務端資料, 這個方案讓服務端資料到了外部網路和服務端。
3.頻寬消耗。資料中心整體外部頻寬的消耗。
4.效能影響。每次HTTP請求和響應都帶有Session資料。

小結

這4種方案都是可用的方案,不過對於大型網站來說,Session Sticky和Session資料集中儲存是比較好的方案,而這兩個方案又各有優勢,需要在具體的場景中做出選擇和權衡。

以上內容來自《大型網站系統與Java中介軟體實踐》