tomcat集群扩展session集中管理

原文链接:http://hi.baidu.com/drnadmhzfnacefe/item/87cead68940ef408a1cf0fa2

tomcat集群扩展session集中管理,Memcached-session-manager使用

研究to mcat做 负载均衡的时候如何实现ha,还有就是不采用session复制的方法做 集群

想到的是将session全部存储在后端的缓存服务器中。

正好网上有这么一个工具Memcached-session-manager(后面简称msm),所以直接扒下来用了。

地址如下:

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


msm支持 stickty(沾粘会话)和non-sticky(非沾粘会话)两种集群方式。

sticky就是前端的loadbanle nce能保证每个用户的请求都路由到了同一个tom cat上。

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

至于msm在这两种方式是怎么处理的看下图:

下图来自javaeye的xxtianxiaxing的博客,我这里引用一下,原文地址为http://xxtianxiaxing.iteye.com/blog/1269704

1. sticky



2. non-sticky



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

可以配置在虚拟服务器的cont ext标签中,也可以在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="fa lse"

<!--下面这个是可选的,自己定义特殊的类注册到kryo自定义转换器中,实现序列化-->

customConverter="com.test.serializer.CustomKryoRegistration"

        />      
  -->
  <!--non sticky 
   <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
      memcachedNodes="n1:localhost:11211"
      sticky="false"
      sessionBackupA sync="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 vo id 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标准序列化还是要低一半多。


   说明:
1、 session存储到memchached实现方案时。他主要功能是修改tomcat的session存储机制,使之能够把session序列化存放到memcached中。
 2、Manager标签属性说明:

className                

               此属性是必须的。

memcachedNodes  

               此属性是必须的。这个属性必须包含你所有运行的memcached节点。每个节点的定义格式为<id>:<host>:<port>。
               多个之间用空格或半角逗号隔开(如:memcachedNodes="n1:localhost:11211,n2:localhost:11212")。
                如果你设置单个memcache节点<id>是可选的,所以它允许设置为<host>:<port>(memcachedNodes="localhost:11211")。
 failoverNodes             

                可选项,属性只能用在非粘连Session机制中。此属性必须包含memcached节点的Id,此节点是Tomcat作为备份使用。多个之间用空格或逗号隔开
memcachedProtocol

                可选项,默认为text。出属性指明memcached使用的存储协议。只支持text或者binary。
 sticky                   

                可选项,默认为true。 指定使用粘性的还是非粘性的Session机制。
lockingMode         

                可选项, 此属性只对非粘性Session有用,默认为none。
                    

指定非粘性Session的锁定策略。他的只有
                        (1)、none:从来不加锁
                        (2)、all: 当请求时对Session锁定,直到请求结束
                        (3)、auto:对只读的request不加锁,对非只读的request加锁
                        (4)、uriPattern:<regexp>: 使用正则表达式来比较requestRUI + "?" + queryString来决定是否加锁,

requestUriIgnorePattern  可选项
                   此属性是那些不能改备份Session的请求的正则表达式。如果像css,javascript,图片等静态文件被同一个Tomcat和同一个应用上下文来提供,这些
                   请求也会通过memcached-session-manager。但是这些请求在一个http会话中几乎没什么改变,所以他们没必要触发Session备份。所以那些静态文件
                   没必要触发Session备份,你就可以使用此属性定义。此属性必须符合java regex正则规范。

sessionBackupAsync 可选项,默认true
                   指定Session是否应该被异步保存到Memcached中。 如果被设置为true,backupThreadCount设置起作用,如果设置false,通过sessionBackupTimeout
                   设置的过期时间起作用。
backupThreadCount 可选项,默认为CPU内核数。
                    用来异步保存Session的线程数(如果sessionBackupAsync="true")。
sessionBackupTimeout  可选项,默认100,单位毫秒
                    设置备份一个Session所用的时间,如果操作超过时间那么保存失败。此属性只在sessionBackupAsync="false"是起作用。默认100毫秒
sessionAttributeFilter 可选项 从1.5.0版本有
                   此属性是用来控制Session中的那个属性值保存到Memcached中的正则表达式。郑则表达式被用来匹配Session中属性名称。如
                   sessionAttributeFilter="^(userName|sessionHistory)$" 指定了只有"userName"和"sessionHistory"属性保存到Memcached中。
                   依赖于选择的序列化策略。
 transcoderFactoryClass 可选,默认为 de.javakaffee.web.msm.JavaSerializationTranscoderFactory
                  此属性值是创建序列化和反序列化保存到Memcached中的Session的编码转换器的工厂类名。这个指定的类必须实现了de.javakaffee.web.msm.TranscoderFactory
                 和提供一个无参的构造方法。 例如其他的有效的实现在其他packages/jars中提供如:msm-kryo-serializer,msm-xstrea-serializer和msm-javolution-serializer.

copyCollectionsForSerialization 可选项,默认false。
customConverter 可选项
enableStatistics 可选项,默认true
                   用来指定是否进行统计。
enabled 可选项,默认true
                    指定Session保存到Memcached中是否可用和是否可以通过JMX进行改变。只用于粘性Session。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值