最近在研究tomcat做負載均衡的時候如何實作ha,還有就是不采用session複制的方法做叢集。
想到的是将session全部存儲在後端的緩存伺服器中。
正好網上有這麼一個工具Memcached-session-manager(後面簡稱msm),是以直接扒下來用了。
位址如下:
[url]http://code.google.com/p/memcached-session-manager/[/url]
[b]msm支援 stickty(沾粘會話)和non-sticky(非沾粘會話)兩種叢集方式。[/b]
sticky就是前端的loadbanlence能保證每個使用者的請求都路由到了同一個tomcat上。
non-sticky則每一次請求都可能路由到了不同的tomcat中。
至于msm在這兩種方式是怎麼處理的看下圖:
下圖來自javaeye的xxtianxiaxing的部落格,我這裡引用一下,原文位址為[url]http://xxtianxiaxing.iteye.com/blog/1269704[/url]
1. [b]sticky[/b]
[img]http://dl.iteye.com/upload/picture/pic/102960/e1fd2d95-609a-37b7-a814-05621194d388.jpg[/img]
2. [b]non-sticky[/b]
[img]http://dl.iteye.com/upload/picture/pic/102962/31e3ccfc-8053-3d77-8fad-0452d8b7abf8.jpg[/img]
用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
可以檢視官方網站的文檔:[url]http://code.google.com/p/memcached-session-manager/wiki/SetupAndConfiguration[/url]
搭建好所有環境之後,采用1 nginx(ip_hash)+2 tomcat6.0.35+sticky(最好用6.0.2以上版本,因為新的msm包裡面使用了6.0.2才有的新方法,不然會報NoSuchMethod-changeSessionId()的錯誤)
[b]驗證是否成功[/b]:
登入釋出的系統(發現這個時候請求全部路由到tomcat1),之後,關閉tomcat1,繼續在裡面做有關session的操作。發現這個時候請求被tomcat2接管,而且session依然保持(從memcached中拿出)。ok,這樣就說明成功了。
non_sticky的配置一樣按上面的方法來驗證是否成功。
*********[b]最後是我在搭建好msm環境後做的一些簡單測試[/b]:***************
測試環境: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人并發)
[b]在sticky的情況下[/b],因為在本地有session的情況下,省略了從memcached取session緩存的情況,序列化次數不多,是以性能隻有大概1/10的損耗。
[b]在non-stikcy的情況下[/b],集中的每次從memcached取session,性能損失了大概一半。
而可以看出,在高并發的情況下,kryo序列化比java标準序列化要好。并發性能大概在java标準序列化一倍以上。而且在搞并發的non-sticky的情況下,session中的多線程并行操作沖突嚴重。lock很多(當然這個lock模式可以設定,甚至可以完全不要鎖)。這也嚴重降低了速度。
[b]又測試了1台nginx(ip_hash做負載均衡)+2tomcat的情況[/b]。
因為暫時沒法模拟多ip的請求,是以所有請求都隻路由到了tomcat1上。采用kryo序列化的政策依然保持了高并發下處理速度不下降的優勢。
還是400多r/s,而java标準序列化還是要低一半多。
[b]
最後推薦采用sticky+kryo的政策來實作msm~![/b]