Tomcat之分布式session共享(MSM)

1. MSM简介

1.1 MSM(memcached session manager)

  • MSM是一个用于解决分布式tomcat环境下session共享问题的开源解决方案
  • 以tomcat插件的方式部署在了tomcat服务器上
  • 即可以从本机内存快速读取Session信息(黏性Session),也可以使用memcached存储Session,以实现高可用

1.2 MSM的特性

  • 支持黏性、非黏性Session
  • 无单一故障点
  • 可处理tomcat故障转移
  • 可处理memcached故障转移
  • 插件式session序列化
  • 允许异步保存session,以提升响应速度
  • 只有当session有修改时,才会将session写回memcached
  • JMX管理&监控

1.3 黏性Session和非黏性Session(一般用于tomcat服务集群)

黏性Session:即session sticky,不复制Session会话

  • 此模式下同一会话中的请求都被派发到同一个tomcat实例上,这样就无须在多台服务器之间实现session共享了
  • 缺点:不能实现failover(故障切换),一旦用户访问的机器挂掉,那么其session就会丢失

非黏性Session:即session replication,复制Session会话

  • 此模式下同一个会话中的请求可以被分配到不同的tomcat实例上进行处理
  • 此时就需要在不同服务器之间同步、复制session,这样即使一台服务器挂掉了,请求在其他服务器上照样可以访问到session信息
  • 缺点:Session复制需要系统资源和网络开销

1.4 MSM解决的问题

问题:

  • 若有一个Tomcat集群,使用粘性session,如何应对单点故障?
  • 为了应对更多的并发量和可用性,可以不断的增加Tomcat节点,但是单点故障仍旧会是个问题
  • 如果使用粘性Session,一个Tomcat故障时,其他Tomcat并不能就干故障Tomcat节点的Session

解决此问题:

  • 将粘性Session同时保存在Memcached中,如果单个Tomcat发生故障,集群中的其他Tomcat可以从Memcached中得到Session信息

2. Tomcat和Memcached的故障转移

2.1 Tomcat的故障转移

  1. MSM安装在tomcat里,tomcat会在本地保留所有会话信息,就如同StandardManager一样
  2. 一个请求完成后,session会被备份到memcached节点
  3. 当服务同一会话的下一次请求时,tomcat可以在本地找到这个会话数据
    • 同一会话的第二次请求处理完成后,会话数据会更新到memcached节点
  4. 若处理某个会话的tomcat挂了,那么下次请求会被路由到另一个tomcat上
    • 但是这个tomcat没有在本地保存该会话的数据,因此它会去相应的memcached中查找此次请求的会话数据并保存到本地
    • (根据请求头中sessionid的后缀)
    • 当这个tomcat处理完此次会话,它会将更新相应memcached节点存储的session信息
  5. 图示:

2.2 memcached的故障转移

  1. msm也实现了memcached的故障转移
    • 当一个memcached节点不可用时,session信息就会被转移到其他memcached节点
    • 与此同时,sessionid会被修改,一个新的JESESSIONID(响应头会有Set-Cookie:JESSIONID;XXXXXXXXXXXXX)会被发送到浏览器端
    • 当使用粘性session(sticky session)时,要确保负载均衡不会给sessionid添加后缀
  2. SESSIONID的格式
    • MSM知道Memcached节点列表,这些节点标识会存储在SESSIONID中
    • SESSIONID值类似:602F7397FBE4D9932E59A9D0E52FE178-n1 【其中n1为Memcached节点标识】

3. MSM原理详解

3.1 MSM原理概述

  • MSM利用Value(Tomcat阀)对Request进行跟踪
  • Request请求来到时,从Memcached加载session
    • Request请求结束时,将tomcat session更新到Memcached,以达到session共享之目的
  • MSM支持黏性(sticky)和非黏性(non-sticky)模式
    • 使用sticky模式时需要配置jvmRoute参数(在Engine标签中配置)
    • 每台tomcat的jvmRoute参数都不能一样

3.2 Sticky和Non-Sticky模式

1)Sticky模式:

  • 结构:
    • tomcat session为主session
    • memcached为备session
  • Request请求到来时:
    • 若tomcat jvmRoute没有发生变化,直接读取tomcat session
    • 若tomcat jvmRoute发生变化,要从memcached加载备session到tomcat
  • Request请求结束时,将tomcat session更新至memcached,以达到主备同步的目的

2)Non-Sticky模式:

  • 结构:
    • tomcat session为中转session
    • memcached1为主session
    • memcached2为备session
  • Request请求到来时,从memcached2加载备session到tomcat
    • 若只有一个memcached节点,或者memcached2出错时
    • 容器中还是没有session,则从memcached1加载主session到tomcat
  • Request请求结束时,将tomcat session更新至主memcached1和备memcached2
    • 并清除tomcat session,以达到主备同步的目的

4. Tomcat分布式session共享(MSM)

4.1 说明

  • 官网介绍说,使用kryo序列化tomcat的效率最高,采用kryo序列化
  • 所需要安装的包:

4.2 No-Sticky模式

  • 说明:
    • 多个tomcat实例时,需要选择Non-Sticky模式,即sticky="false"
  • 配置示例:
    # 在<Context>中添加
    <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
         # 配置memcached的节点信息,多个memcached节点中间需要使用空格或逗号隔开
            memcachedNodes="n1:192.168.10.203:11211,n2:192.168.10.205:11211"  
            lockingMode="auto"            # 可选值,默认为none,只对non-sticky有效
            sticky="false"                # 使用Non-Sticky模式
            sessionBackupAsync="false"    # 可选值,默认为true,是否以异步的方式存储到memcached
         # 可选值,制定忽略那些请求的session操作,一般制定静态资源如css,js一类的
            requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"  
            transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
            /> 

4.3 Sticky模式

  • 说明:
    • 故障转移配置节点(failoverNodes),不能使用在Non-Stick模式,多个使用空格或逗号分隔开,配置某个节点为备份节点
    • 当其他节点都不可用时才会存储到备份节点,适用于stick模式(一台tomcat,多台memcached)
  • 配置示例:
    # 在<Context>中添加:
    <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
         #多个memcached之间用空格或逗号隔开都可以
            memcachedNodes="n1:192.168.10.203:11211,n2:192.168.10.205:11211"
            sticky="true"
            failoverNodes="n2"                                           
            requestUriIgnorePattern=".*\.(png|gif|jpg|css|js|swf|flv)$"
            transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
            copyCollectionsForSerialization="true"
            />

4.4 测试的index.jsp页面

<%@ page language="java" %>
<html>
        <head><title>TomcatB</title></head>
        <body>
                <h1><font color="red">TomcatB</font></h1>
                <table align="centre" border="1">
                        <tr>
                                <td>Session ID</td>
                <% session.setAttribute("www.node1.com","www.node1.com"); %>
                                <td><%= session.getId() %></td>
                        </tr>
                        <tr>
                                <td>Created on</td>
                                <td><%= session.getCreationTime() %></td>
                        </tr>
                </table>
                <h1>10.0.0.204</h1>
        </body>
</html>

4.5 在memcached中查看缓存的session信息

stats items
STAT items:3:number 1
STAT items:3:age 24
STAT items:3:evicted 0
STAT items:3:evicted_nonzero 0
STAT items:3:evicted_time 0
STAT items:3:outofmemory 0
STAT items:3:tailrepairs 0
STAT items:3:reclaimed 0
STAT items:3:expired_unfetched 0
STAT items:3:evicted_unfetched 0
STAT items:5:number 1
STAT items:5:age 24
STAT items:5:evicted 0
STAT items:5:evicted_nonzero 0
STAT items:5:evicted_time 0
STAT items:5:outofmemory 0
STAT items:5:tailrepairs 0
STAT items:5:reclaimed 0
STAT items:5:expired_unfetched 0
STAT items:5:evicted_unfetched 0
END
stats cachedump 3 0
ITEM bak:validity:C556BD8AF979FDAC3F311ACA1E3E2318-n2.TomcatB [20 b; 1576173776 s]
END
stats cachedump 5 0
ITEM bak:C556BD8AF979FDAC3F311ACA1E3E2318-n2.TomcatB [97 b; 1576175567 s]
END
  • 经过测试,发现session一样,测试成功

 

posted @ 2020-06-22 18:40  Praywu  阅读(817)  评论(0编辑  收藏  举报