tomcat集群扩展session集中管理,Memcached-session-manager使用总结 * 博客分类: * tomcat集群 * hacss
javatomcatwebhasession manager 最近在研究tomcat作负载均衡的时候如何实现ha,还有就是不采用session复制的方法作集群。前端
想到的是将session所有存储在后端的缓存服务器中。java
正好网上有这么一个工具Memcached-session-manager(后面简称msm),因此直接扒下来用了。nginx
地址以下:web
http://code.google.com/p/memcached-session-manager/apache
msm支持 stickty(沾粘会话)和non-sticky(非沾粘会话)两种集群方式。json
sticky就是前端的loadbanlence能保证每一个用户的请求都路由到了同一个tomcat上。后端
non-sticky则每一次请求均可能路由到了不一样的tomcat中。缓存
至于msm在这两种方式是怎么处理的看下图:tomcat
下图来自javaeye的xxtianxiaxing的博客,我这里引用一下,原文地址为http://xxtianxiaxing.iteye.com/blog/1269704
sticky
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标准序列化仍是要低一半多。