1. 程式人生 > >叢集伺服器Session同步及一種基於Memcached的session同步

叢集伺服器Session同步及一種基於Memcached的session同步

1 Session的叢集管理

事實上,網站總是有狀態的。每一個登入資訊、使用者資訊常常被儲存在session內部。而當一個網站被部署在不止一臺伺服器的時候,就會遇到session同步的問題。事實上即使一個很小的網站,也要至少有兩臺伺服器互為備份,分單流量是必須得,更重要的是無縫切流量升級。為了保證服務的不間斷又要進行網站的維護升級,切流量是最簡單的。那麼如何保證切流量的時候session也會跟著同步過去呢?在叢集環境下,大致有以下幾種手段

1.1 Session複製

這是一種在早期應用系統中使用較多的伺服器session管理方式。應用伺服器開啟Web容器的session的複製功能,在叢集中的幾臺伺服器之間同步session物件,這樣一臺伺服器宕機不會導致session資料丟失。即每一臺伺服器都持有叢集中所有的session,每次訪問僅從本機獲取就可以了。其工作形式如下所示:

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

1.2 Session繫結

Session繫結可以利用負載均衡的源地址Hash演算法實現,負載均衡伺服器總是將來自同一個IP地址的訪問分發到同一臺伺服器上。這樣整個會話期間,使用者所有的請求都來自一臺伺服器,保證了Session總是從這臺伺服器獲取。其工作形式如下圖所示

但是這樣的系統顯然不符合我們對系統的需求。如果一臺伺服器宕機,那麼其處理的所有請求Session會話全部丟失,使用者因為切換伺服器後沒有Session而導致無法完成業務。

1.3 利用Cookie記錄Session

這種管理方式將Session記錄在客戶端,每次請求伺服器的時候,將Session放在請求中傳送給伺服器,伺服器處理完成後再將修改後的Session響應給客戶端。

利用Cookie記錄當然也有缺點,比如Cookie大小限制,能記錄的資訊也有限,因為很多時候我們在Session中儲存的也並非String型別的記錄。每次請求都需要傳輸Cookie,影響效能;另外如果使用者關閉Cookie功能就不能用了。但是這種方式因此高可用性、支援伺服器的線性伸縮,許多網站都在使用這種方式。我的學校網站也應用了這種技術。

1.4 Session伺服器

如果有這樣一個伺服器,可用性高、伸縮性好、效能也不錯,對資訊大小又沒有限制,那它就是Session伺服器。利用獨立部署的Session伺服器統一管理Session,應用伺服器每次讀寫Session時,都訪問Session伺服器。其工作形式如下所示。

這種方式實際上是將應用伺服器的狀態分離,分為無狀態的應用伺服器和有狀態的Session伺服器,然後針對這兩種伺服器的不同特性分別設計其架構。

對於有狀態的Session伺服器,一種比較簡單的方式是利用分散式快取、資料庫等。

2 基於Memcached的Session同步實現

2.1 系統結構

本人利用Memcached叢集簡單實現了Tomcat Session的同步管理。首先貼出系統的結構圖

系統環境中所有伺服器都是CentOS6.5的環境

系統中有兩臺記憶體較大的伺服器安裝了Memcached服務,作為Session叢集

兩臺伺服器分別部署了Tomcat8作為應用伺服器

一個伺服器部署了Apache2.4作為負載均衡伺服器

2.2 原理

這種基於Memcached的Session管理(memcached-session-manager 簡稱SMS),利用的是Tomcat對Request跟蹤。Request到來時,從memcached中獲取對應的session,request結束時,將tomcat中的session更新至memcached伺服器。目前支援sticky和no-sticky模式:

  • sticky模式:tomcat中的session作為主session,memcached中的為備份session。發生request時,首先檢查容器是否發生變化,發生變化則從memcached載入Session到本地,否則不載入,直到request請求結束。
  • Non-sticky模式:memcached1為主session服務,memcached2為備份session,tomcat中的session為備份session。Request請求到來時,從memcached 2載入備session 到 tomcat,(當容器中還是沒有session 則從memcached1載入主 session 到 tomcat, 這種情況是隻有一個memcached節點,或者有memcached1 出錯時),Request請求結束時,將tomcat session更新至 主memcached1和備memcached2,並且清除tomcat session 。以達到主備同步之目的。

2.3 配置

本人採用的kryo序列化的方式

(1)修改兩臺tomcat伺服器的conf目錄下 context.xml檔案,n1,n2為兩臺memcached伺服器的地址和埠號

<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
      memcachedNodes="n1:172.20.201.191:50120 n2:172.18.124.5:50120"   
   lockingMode="auto"
   sticky="false" 
   requestUriIgnorePattern= ".*\.(png|gif|jpg|css|js)$"    
   sessionBackupAsync= "false"   
   sessionBackupTimeout= "100"    
   copyCollectionsForSerialization="true"   
   transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"    
       />

(2)將需要的jar包放在tomcat的lib目錄下 需要的jar包如下:

asm-4.0

kryo-1.04(必須是這個版本 )

kryo-serializers-0.11(必須是這個版本)

memcached-session-manager-1.8.3

memcached-session-manager-tc8-1.8.3(與tomcat版本對應)

minlog-none-1.2

msm-kryo-serializer-1.8.3

reflectasm-1.07

spymemcached-2.10.3

然後啟動tomcat伺服器就可以了,

注:在配置以上兩步之前,需要保證的時候apache伺服器已經可以負載均衡tomcat兩臺伺服器。

2.4 驗證

(1)訪問Apache伺服器地址,負載到其中一臺伺服器


(2)停止掉被負載到的這臺伺服器,重新整理頁面,可以看到伺服器已經切換,但sessionId沒有變化。已實現Session同步功能。