zoukankan      html  css  js  c++  java
  • 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~!

  • 相关阅读:
    Linux常用操作命令
    Linux下查看CPU型号,内存大小,硬盘空间命令
    PhpExcel中文帮助手册|PhpExcel使用方法
    PHP操作cookie函数:setcookie()与setrawcookie()
    利用phantomjs模拟QQ自动登录
    无法在同一张表上查询和更新的问题解决方法
    App开放接口api安全性—Token签名sign的设计与实现
    开放api接口签名验证
    bootstrap字体图标
    booatrap中的表格样式
  • 原文地址:https://www.cnblogs.com/interdrp/p/3450437.html
Copyright © 2011-2022 走看看