1. 程式人生 > >分散式叢集Session快取丟失問題

分散式叢集Session快取丟失問題

前言

    Session快取共享的背景和意義:通常我們搭建完叢集之後,不得不考慮的一個問題就是使用者訪問產生的session如何處理。如果不做任何處理的話,使用者將出現頻繁登入的現象,比如叢集中存在A、B兩臺伺服器,使用者在第一次訪問網站時,Nginx通過其負載均衡機制將使用者請求轉發到A伺服器,這時A伺服器就會給使用者建立一個Session。當用戶第二次傳送請求時,Nginx將其負載均衡到B伺服器,而這時候B伺服器並不存在Session,所以就會將使用者踢到登入頁面。這將大大降低使用者體驗度,導致使用者的流失,這種情況是專案絕不應該出現的。

尤其是在大型分散式叢集web專案中,必須得處理和解決Session快取共享機制的問題,接下來討論幾種常見的Session快取丟失的解決方案:

一、Ip_Hash

ip_hash方法,這個可謂是最為簡單的方法了,我們在硬體和軟體(程式侵入)上無需做出優化和改變;只需在負載均衡軟體裝置的配置檔案中設定好就行了。目前三大主流軟體負載均衡器如:LVS、Nginx、HAproxy;我們以Nginx為例。

它的原理是:使用者(客戶端)在請求伺服器之前,均需要經過Nginx進行反向轉發路由;那麼配置了ip_hash均衡權重後,Nginx會根據客戶端請求的ip地址進行雜湊演算法對映到某臺伺服器,只要該使用者訪問請求的ip地址不發生變更,伺服器的裝置也不變化,那麼之後該使用者每次訪問的請求豆漿固定到這太伺服器上。如:A B兩臺伺服器,使用者1經ip_hash對映到A之後,那麼之後每次請求都將不變的對映到機器A。

優點:簡單,不需要對session做任何處理。

缺點:缺乏容錯性,如果當前訪問的伺服器發生故障,使用者被轉移到第二個伺服器上時,他的session資訊都將失效。

適用場景:發生故障對客戶產生的影響較小;伺服器發生故障是低概率事件。

實現方式:以Nginx為例,在upstream模組配置ip_hash屬性即可實現粘性Session。

upstream mycluster{
    #這裡新增的是上面啟動好的兩臺Tomcat伺服器
     ip_hash;#粘性Session
     server 192.168.22.229:8080 weight=1;
     server 192.168.22.230:8080 weight=1;
}

另:Nginx有3種常見均衡權重配置(輪詢(預設)、ip_hash、指定權重(自定義分配))。

二、伺服器session複製

原理:任何一個伺服器上的session發生改變(增刪改),該節點會把這個 session的所有內容序列化,然後廣播給所有其它節點,不管其他伺服器需不需要session,以此來保證Session同步。

優點:可容錯,各個伺服器間session能夠實時響應。

缺點:會對網路負荷造成一定壓力,如果session量大的話可能會造成網路堵塞,拖慢伺服器效能。

實現方式:

session複製

應用伺服器開啟Web容器的session的複製功能,在叢集中的幾臺伺服器之間同步session物件,這樣一臺伺服器宕機不會導致session資料丟失。即每一臺伺服器都持有叢集中所有的session,每次訪問僅從本機獲取就可以了。

從session複製的幾條線就可以看出,這種方式僅適用用小型叢集。當服務叢集規模很大時,叢集伺服器間的複製就需要大量的通訊,佔用大量網路資源,甚至會出現記憶體不夠的情況。

三、統一Session快取(共享機制)

第三種方法,也是最具有優勢和大廠經常被採用的一種方案。尤其是大型分散式架構的系統,這種方案的優勢非常的突出。使用分散式快取方案比如memcached、Redis,但是要求Memcached或redis必須是叢集。本文以Redis為例講述Session共享機制。

  • 配置Filter過濾攔截器,攔截Session
<filter>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
  • 經過Redis或Memcache再快取
  • 防止在Session中的物件必須是可序列化的
  • SpringSessionRepositoryFilter的順序必須在其他獲取Session的filter之前
  • Session的失效時間由Redis節點過期時間決定,原有配置無效
Session統一快取

優點:某個應用伺服器出現問題,session不會丟失;對伺服器的配置效能要求最低階,輕鬆實現高併發訪問;對程式無侵入性。

缺點:快取Session的memcached或Redis一旦掛掉,則session丟失。

 

綜上:一般大型分散式系統,首選第三種(統一Session快取)Session共享機制。

 

關注個人技術公眾號:nick_coding1024

不定期分享最新前沿技術框架和bat大廠常用技術等,加群不定期分享行業內大牛直播講課以及獲得內退一線網際網路公司機會。