1. 程式人生 > >tomcat叢集擴充套件session集中管理,Memcached-session-manager使用總結

tomcat叢集擴充套件session集中管理,Memcached-session-manager使用總結

最近在研究tomcat做負載均衡的時候如何實現ha,還有就是不採用session複製的方法做叢集。

想到的是將session全部儲存在後端的快取伺服器中。

正好網上有這麼一個工具Memcached-session-manager(後面簡稱msm),所以直接扒下來用了。

地址如下:

http://code.google.com/p/memcached-session-manager/


msm支援 stickty(沾粘會話)和non-sticky(非沾粘會話)兩種叢集方式。

sticky就是前端的loadbanlence能保證每個使用者的請求都路由到了同一個tomcat上。

non-sticky則每一次請求都可能路由到了不同的tomcat中。

至於msm在這兩種方式是怎麼處理的看下圖:

下圖來自javaeye的xxtianxiaxing的部落格,我這裡引用一下,原文地址為
http://xxtianxiaxing.iteye.com/blog/1269704


1. sticky



2. non-sticky



用msm的session管理manager替代tomcat自身的standardManager。

可以配置在虛擬伺服器的context標籤中,也可以在context.xml裡面全域性配置。



<!--sticky
       
  <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
        memcachedNodes="n1:localhost:11211"
        requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
        transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
      copyCollectionsForSerialization="false"

<!--下面這個是可選的,自己定義特殊的類註冊到kryo自定義轉換器中,實現序列化-->

customConverter="com.test.serializer.CustomKryoRegistration"

        />      
  -->
  <!--non sticky 
   <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
      memcachedNodes="n1:localhost:11211"
      sticky="false"
      sessionBackupAsync="false"
      lockingMode="auto"
      requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
      transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
    />

上面採用的序列化方式是kryo,根據官方提供的資料,這個的序列化效率是最好的,我下面有一些簡單的測試。

感覺kryo的效率主要體現在高併發下面。如果非高併發感覺跟java的自帶io差不多。如果不使用kryo進行序列化,採用java預設方式的話,請將transcoderFactoryClass改為:de.javakaffee.web.msm.JavaSerializationTranscoderFactory

另外在使用kryo進行序列話的時候,有時候會報序列話錯誤。我開始就報ConcrrentHashMap這個類不能序列化的錯誤。tomcat在的session的Atrribute使用了這個資料結構來儲存。要解決這個問題,需要自己寫一個類,將這些特殊的類註冊進去。然後打個jar包放tomcat的lib下。就ok了。



下面是例子:

package com.test.serializer;
import java.util.concurrent.ConcurrentHashMap;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.serialize.MapSerializer;

import de.javakaffee.web.msm.serializer.kryo.KryoCustomization;

public class CustomKryoRegistration implements KryoCustomization {
public void customize(Kryo kryo) {
kryo.register(ConcurrentHashMap.class, new MapSerializer(kryo));
}
}
把這個類打好jar包放tomcat的lib目錄下。然後還需要在context中配置customConverter="com.test.serializer.CustomKryoRegistration",這樣就OK了。

另外整合kryo序列化的環境需要以下jar包。剛開始googleCode的官方網站上沒寫。搞了半天,後來提醒原作者加上了:

kryo-serializer: msm-kryo-serializer, kryo-serializers, kryo, minlog, reflectasm, asm-3.2

其他序列化方式(java自帶的序列化方式外的3方序列化方式)需要的jar:

javolution-serializer: msm-javolution-serializer, javolution-5.4.3.1
xstream-serializer: msm-xstream-serializer, xstream, xmlpull, xpp3_min
flexjson-serializer: msm-flexjson-serializer, flexjson
可以檢視官方網站的文件:
http://code.google.com/p/memcached-session-manager/wiki/SetupAndConfiguration


搭建好所有環境之後,採用1 nginx(ip_hash)+2 tomcat6.0.35+sticky(最好用6.0.2以上版本,因為新的msm包裡面使用了6.0.2才有的新方法,不然會報NoSuchMethod-changeSessionId()的錯誤)

驗證是否成功

登入釋出的系統(發現這個時候請求全部路由到tomcat1),之後,關閉tomcat1,繼續在裡面做有關session的操作。發現這個時候請求被tomcat2接管,而且session依然保持(從memcached中拿出)。ok,這樣就說明成功了。

non_sticky的配置一樣按上面的方法來驗證是否成功。





*********最後是我在搭建好msm環境後做的一些簡單測試
:***************



測試環境:T5870 2.0G cpu,記憶體2G小本本,win7系統。tomcat,memcache全部裝win7上。啟動一個memcahed服務給了32m記憶體。tmcat52m記憶體。



ok,首先是前面沒有負載均衡,單個tomcat的情況,請求一個sevlet連結,連結就是從session取個值出來的操作。

用apache ab,-C 引數帶上cookie引數模擬有session的請求,100人,共5000次請求是下面的結果:

不用msm: 1000req/s
msm-sticky kryo: 850req/s
msm-sticky java標準序列化: 830req/s
msm-nonsticky kryo : 440/s(50人併發) 430/s(100人併發)
msm-nosticky java標準序列化 : 480/s(50人併發) 270/s(100人併發)

在sticky的情況下,因為在本地有session的情況下,省略了從memcached取session快取的情況,序列化次數不多,因此效能只有大概1/10的損耗。

在non-stikcy的情況下,集中的每次從memcached取session,效能損失了大概一半。

而可以看出,在高併發的情況下,kryo序列化比java標準序列化要好。併發效能大概在java標準序列化一倍以上。而且在搞併發的non-sticky的情況下,session中的多執行緒並行操作衝突嚴重。lock很多(當然這個lock模式可以設定,甚至可以完全不要鎖)。這也嚴重降低了速度。

又測試了1臺nginx(ip_hash做負載均衡)+2tomcat的情況

因為暫時沒法模擬多ip的請求,所以所有請求都只路由到了tomcat1上。採用kryo序列化的策略依然保持了高併發下處理速度不下降的優勢。

還是400多r/s,而java標準序列化還是要低一半多。


最後推薦採用sticky+kryo的策略來實現msm~!