1. 程式人生 > >使用者Session 會話機制

使用者Session 會話機制

博由

    本文針對:使用者Session在不同的系統場景如何解決?進行分析和記錄。

Session策略

1個站點

在展開話題之前,先看看一個普通的分散式站點是咋樣的?
分散式站點

[1] 發生位置:使用者側(例如:瀏覽器)
[2] 實現方式:將使用者資訊(會話資訊)儲存在cookie中,在每次請求時,將這些資訊傳送到server進行解析;一般來說,cookie儲存的會話內容都會進行加密(例如:md5/sha等);這種方式主要依賴於cookie的存在,cookie本身是儲存在使用者側,因此安全性不能得到保證,容易被串改和劫持;還有一個點就是cookie儲存的內容是有限的,只能存在小資料;
互動流程:

cookie互動

總結:
1、cookie 本身問題(儲存有限、安全性不高);
2、實現簡單;
如果出現cookie禁用情況,可以通過明文URL傳遞引數可以解決,但是同樣是安全性問題;

Session Sticky(粘性會話)

[1] 發生位置:負載均衡(LVS)部分;
[2] 實現方式:負責均衡來記錄使用者方式伺服器的關係,例如:使用者1 訪問了 伺服器1,那麼每次確保使用者1路由到伺服器1,這樣就能確保和單機Session的情況一樣,但是缺點就是:
1、LVS儲存了使用者側和伺服器的關係,變成了有狀態;
2、如果伺服器1掛了,那麼使用者1要麼無法訪問,要麼就需要進行重新登陸;
互動方式:

Session Sticky

總結:通過中間負載裝置,每次使用者訪問時,會儲存使用者與伺服器之間的關係,確保每次該使用者都路由到同一個伺服器,從而和單機情況基本一致,就不會出現重複登陸情況,那麼這種情況會導致兩個不好的點:
1、負載裝置:從無狀態變成有狀態,並且儲存了使用者和伺服器關係資訊,儲存容量也需要進行考慮;
2、單機場景:這種方式其實就是避免的分散式叢集情況的Session不一致問題,但是卻同樣引來了單點伺服器的問題,如果伺服器掛了:
a、負載均衡不做處理:那麼使用者是無法繼續訪問站點;
b、路由到其他可用伺服器,那麼需要使用者重新登陸;

Session Replication(Session複製)

[1] 發生位置:服務端叢集側;
[2] 實現方式:後臺伺服器之間進行Session資料複製,這種方式僅僅適用於伺服器數量少的情況,如果多的話,伺服器之間的資料複製,會越來越到,這只是一種實現方式,正常情況不會這麼做的。
互動方式:

Session Replication

總結:
如果要在伺服器這一層來解決Session問題,那麼只要確保伺服器之間Session資料是一致的就可以,換句話說,1-n號機儲存的Session保持一致,那麼無論那一臺伺服器掛了,都不需要重新登陸,這是實現的原理。那麼就需要提供一個保證伺服器Session一致的工具;如果說叢集數量比較大,那麼複製的動作非常之大,假設1號機Session變化(刪除、更新、增加)都需要同步到2-n號機,負擔是非常之大的;一般只適用於小叢集數量和使用者量少的情況,不是很推薦使用;

集中儲存

[1] 發生位置:儲存側(例如:DB[2] 實現方式:將會話資料儲存在諸如:資料庫、redis等儲存裝置中;實現原理很簡單,就是集中Session儲存,不會存在某個伺服器掛了,需要使用者重新登陸的情況,如果訪問量比較大的話,資料庫的壓力會比較大,這個可以通過做Session cache來提高效率(一般採用redismemcache等);
互動方式:

集中儲存

總結:Session複製是依據Session資料一致的問題來解決的,那麼還有一個思路就是:將Session資料共享處理,集中化儲存。因此我們需要選擇一個集中儲存Session的儲存媒介(一般是資料庫,例如:mysql),這樣的化會建立三層關係:
第一層:伺服器Session快取;
第二層:快取中介軟體(redis);
第三層:儲存媒介(MySQL);
如果使用者進行訪問時,會先看訪問的伺服器Session嚴重是否ok,如果不ok,那麼查詢redis,最後再查詢mysql,最終mysql不存在才需要使用者重新登陸。這裡需要注意的是:快取一致性的問題,本文不針對展開。
這種方式使用比較常見。

總結

解決分散式Session問題,我們針對比較常見的分散式站點的結構佈局,在不同層通過不同的方法來解決session問題。可以分為:
1、使用者側:例如:瀏覽器,可以通過Cookie儲存使用者密文驗證資訊,優點就是處理很簡單,缺點就是安全性問題;
2、負載側:單機環境下是不存在Session問題,那麼我們可以通過負載路由策略來保證使用者的訪問到固定的機器上,這樣就構造了一個單機環境,那麼單點環境存在的問題,在這裡依舊存在,例如:伺服器掛了,使用者訪問不了;雖然可以通過路由策略轉到其他可用伺服器,但是還是需要使用者重新登陸;
3、服務側:分散式環境下由於使用者流量匯入到不同的機器上,會導致每臺機器儲存的Session不盡相同,那麼使用者一會訪問伺服器,一會訪問伺服器2,就會導致使用者重新登陸,因此我們可以通過考慮伺服器間的Session資料是一致的,這樣就需要一個工具來保證Session在變化時伺服器之間的Session資料同步,這種方式很少使用,因為當用戶資料(Session)多時,伺服器多時,會導致Session的同步很多很頻繁,效率不好。但是也不失為一種解決方式;
4、儲存側:思路就是Session資料共享,那麼就需要儲存Session資料的媒介,一般會是資料庫;這樣就不會出現伺服器之間的Session複製,同時也可以集中管理和維護Session資訊,但是問題也有,就是當訪問量大的時候,資料庫可能成為瓶頸,這個可以通過加入cache層來解決問題,這種方式,比較常用;