Tomcat session共享—MSM一、原理MSM(memcached-session-manager) 支持tomcat6 和tomcat7 ,利用 Value (Tomcat 阀)对Request进行跟踪。
Request请求到来时,从memcached加载session,Request请求结束时,将tomcat session更新至memcached,以达到session 共享之目的,支持 sticky 和 non-sticky 模式。
Sticky 模式:tomcat session 为主session, memcached为备 session。
Request 请求到来时,从memcached加载备 session 到 tomcat (仅当tomcat jvmroute发生变化时,否则直接取tomcat session);Request请求结束时,将tomcat session更新至memcached,以达到主备同步之目的。
Non-Sticky模式:tomcat session 为中转session, memcached1 为主 sessionmemcached 2 为备session。
Request请求到来时,从memcached 2加载备 session 到 tomcat,(当容器中还是没有session 则从memcached1加载主 session 到 tomcat,这种情况是只有一个memcached节点,或者有memcached1 出错时),Request请求结束时,将tomcat session更新至主memcached1和备memcached2,并且清除tomcat session 。
以达到主备同步之目的。
二、配置1.sticky<Context><Manager className=" de.javakaffee.web.msm.MemcachedBackupSessionManager"memcachedNodes="n1:localhost:11211 n2:localhost:11212"failoverNodes="n1"requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"/></Context>2.non-sticky<Context><Manager className=" de.javakaffee.web.msm.MemcachedBackupSessionManager" memcachedNodes="n1:localhost:11211 n2:localhost:11212"sticky="false"lockingMode="uriPattern:/path1|/path2"requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.Kry oTranscoderFactory"/></Context>3.jvmroute配置$CATALINA_HOME/conf/server.xml#每台机器jvmRoute不能相同 jvmRoute="tomcat2"<Engine name="Catalina" defaultHost="localhost"jvmRoute="tomcat2">配置$CATALINA_HOME/conf/context.xml<Context>详见下4.日志在该日志文件中添加配置。
$CATALINA_HOME/conf/logging.properties.de.javakaffee.web.msm.level=FINE5.jarkryo-1.03.jarkryo-serializers-0.8.jarmemcached-2.4.2.jarmemcached-session-manager-1.5.0.jarmemcached-session-manager-tc6-1.5.0.jarminlog-1.2.jarmsm-kryo-serializer-1.5.0.jar三、流程图1.sticky2.non-sticky基于kryo序列化方案的memcached-session-manager多memcached节点配置上次基于Java IO的序列化方案配置了memcached-session-manager,但是性能不好,现在先简单配置成基于kryo的Xml代码1.<Context path="/mobilemail" docBase="D:\webapp\WebRoot" reloadable="true">2.<Manager3.className= "de.javakaffee.web.msm.MemcachedBackupSessionManager"4.memcachedNodes= "n1:192.168.112.1:11211,n2:192.168.112.2:11211"5.sticky="false"6.lockingMode="auto"7.requestUriIgnorePattern= ".*\.(png|gif|jpg|css|js)$"8.sessionBackupAsync= "false"9.sessionBackupTimeout= "0"10.memcachedProtocol="binary"11.copyCollectionsForSerialization="true"12.transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"13.customConverter="mons.CustomKryoRegistration"14. />15.</Context>注意customConverter配置的com.test.serializer.CustomKryoRegistration 这个类是自己写的类,是用来注册一些特殊类型的,同时自己负责对这些类型的序列化,可以放在项目里,也可以单独打个jar包,把以后遇到的所有复杂类型都在这里即可。
项目里遇到的kryo没有注册到的类就是session里的java.util.concurrent.ConcurrentHashMap这个类,反序列化的时候本来可以做得更高效些,这里只是为了演示,直接用kryo自带的MapSerializer来反序列化Java代码1.package com.test.serializer;2.import java.util.concurrent.ConcurrentHashMap;3.4.import com.esotericsoftware.kryo.Kryo;5.import com.esotericsoftware.kryo.serialize.MapSerializer;6.7.import de.javakaffee.web.msm.serializer.kryo.KryoCustomization;8.9.public class CustomKryoRegistration implements KryoCustomization {10. public void customize(Kryo kryo) {11. kryo.register(ConcurrentHashMap.class, new MapSerializer(kryo));12. }13.}感兴趣的同学请参见msm-kryo-serializer-1.4.0.jar注册wicket的MiniMap 的流程(de.javakaffee.web.msm.serializer.kryo.WicketMiniMapRegistration里对MiniMap使用kryo-serializers-0.8.jar中的de.javakaffee.kryoserializers.wicket.MiniMapSerializer 单独处理)要使用kryo进行序列化需额外添加kryo的jar包,我使用的是kryo-1.04,所需要的jar包在附件里。
添加依赖的时候请注意不要引起jar包冲突,比较常见的是使用cglib和所依赖的asm的冲突,我的解决办法是留下kryo所需要的asm-3.3.1.jar,删去其他版本的asm,再将原先项目里的cglib换成cglib-nodep-2.2.jar。