Tomcat Cluster官网:https://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html(tomcat7.0)

场景:

tomcat1 tomcat2
    |            |
--------|---------
      nginx

tomcat版本:7.0.59

1.后端应用为2台tomcat容器,并且配置了Tomcat Cluster实现session同步;
2.nginx为前端web服务器,负责反向代理和负载均衡(简单轮训),配置如下:

upstream tomcat {
  server 192.168.70.130:8080;
  server 192.168.70.131:8080;
}

3.在应用代码中将一个map对象存放在session中,即:

Map<String, Object> map = new HashMap<String, Object>();
map.put("email", "");
req.getSession().setAttribute(Constants.KEY_SESSION_MAP, map);

问题:
t1: 请求1经过nginx访问到tomcat1,此时将session中保存的map对象取出来,同时更改map对象保存的<key:value>值:

Map<String, Object> map = (Map<String, Object>) req.getSession().getAttribute(Constants.KEY_SESSION_MAP);
map.put("email", "");

t2: 请求2经过nginx访问到tomcat2,取出session中保存的map对象,并取得其中的<key:value>值:

Map<String, Object> map = (Map<String, Object>) req.getSession().getAttribute(Constants.KEY_SESSION_MAP);
map.get("email");

这时发现,在tomcat2中取得的map对象<key:value>与在tomcat1中修改后存放的<key:value>不一致!
具体来说,在tomcat1中map对象修改后存放的<key:value>值为:<"email":"67890">,但是在tomcat2中map对象取出来的<key:value>依然为之前的值:<"email":"12345">。
看起来,tomcat的集群session同步失效了?!

原因:

Data is only replicated if the session has changed (by calling setAttribute or removeAttribute on the session).

即:只有当明确调用session.setAttribute()或者session.removeAttribute()时才会同步session数据。
详见:https://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html Cluster Information
Tomcat集群配置:

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
      channelSendOptions="8">
  <Manager className="org.apache.catalina.ha.session.DeltaManager"
        expireSessionsOnShutdown="false"
        notifyListenersOnReplication="true"/>
  <Channel className="org.apache.catalina.tribes.group.GroupChannel">
    <Membership className="org.apache.catalina.tribes.membership.McastService"
            address="228.0.0.4"
            port="45564"
            frequency="500"
            dropTime="3000"/>
    <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
            address="auto"
            port="4000"
            autoBind="100"
            selectorTimeout="5000"
            maxThreads="6"/>
    <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
       <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
    </Sender>
    <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
    <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
  </Channel>
  <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
        filter=".*\.gif|.*\.js|.*\.jpeg|.*\.jpg|.*\.png|.*\.htm|.*\.html|.*\.css|.*\.txt"/>
  <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
  <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
          tempDir="/tmp/war-temp/"
          deployDir="/tmp/war-deploy/"
          watchDir="/tmp/war-listen/"
          watchEnabled="false"/>
  <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener" />
  <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener" />
</Cluster>

如上所示,Tomcat集群使用org.apache.catalina.ha.session.DeltaManager管理session同步,追踪源码:

@Override
public Session createEmptySession() {
return getNewDeltaSession() ;
}
/**
* Get new session class to be used in the doLoad() method.
*/
protected DeltaSession getNewDeltaSession() {
return new DeltaSession(this);
}

显然,DeltaManager创建的Session实例为org.apache.catalina.ha.session.DeltaSession对象实例。

DeltaSession保存数据时序图:

如上图所示,org.apache.catalina.ha.session.DeltaSession在保存数据时将发送集群消息,以实现session数据同步。

解决办法:
当session中保存的数据发生改变时,需要重新调用session.setAttribute(),这样才会在集群中同步最新的session数据,即:

// 修改session中map对象保存的值
Map<String, Object> map = (Map<String, Object>) req.getSession().getAttribute(Constants.KEY_SESSION_MAP);
map.put("email", "67890");
req.getSession().setAttribute(Constants.KEY_SESSION_MAP, map); // session保存的值发生改变时,必须重新调用session.setAttribute()触发session数据同步

总结:
在使用Tomcat Cluster进行session同步时,保存在session中的数据如果发生了变化,则必须重新调用session.setAttribute()进行保存。这样才能触发Tomcat发送集群消息,将最新修改的session数据同步到其他节点上。其实不难理解,Tomcat Cluster之所以采用这样的数据同步机制,就是希望当session发生变化(通过保存或删除数据)时才进行同步,减少不必要的集群同步消息。

 

tomcat cluster session同步时保存map数据遇到的问题的更多相关文章

  1. 用SugarORM快速开发需要同步和保存大量数据的Android互联网客户端

    最近开发的一个项目主要有两个特点,这两点也是在项目开发前需要着重去规划解决方案的: 需要和Rest服务端请求大量的数据 同时这些数据本地也要保存到sqlite数据库 对于第一点,目前的Volley.G ...

  2. tomcat集群和负载均衡的实现(session同步)

      (一)环境说明 (1)服务器有4台,一台安装apache,三台安装tomcat (2)apache2.0.55.tomcat5.5.15.jk2.0.4.jdk1.5.6或jdk1.4.2 (3) ...

  3. 【转】web集群时session同步的3种方法

    转载请注明作者:海底苍鹰地址:http://blog.51yip.com/server/922.html 在做了web集群后,你肯定会首先考虑session同步问题,因为通过负载均衡后,同一个IP访问 ...

  4. Apache shiro集群实现 (八) web集群时session同步的3种方法

    Apache shiro集群实现 (一) shiro入门介绍 Apache shiro集群实现 (二) shiro 的INI配置 Apache shiro集群实现 (三)shiro身份认证(Shiro ...

  5. web集群时session同步的3种方法

    在做了web集群后,你肯定会首先考虑session同步问题,因为通过负载均衡后,同一个IP访问同一个页面会被分配到不同的服务器上,如果session不同步的话,一个登录用户,一会是登录状态,一会又不是 ...

  6. nginx和tomcat配置负载均衡和session同步

    一.背景 因业务需求,现需配置多台服务器,实现负载均衡. 二.解决方案 使用 nginx + tomcat,在这一台应用服务器部署一个nginx和两个tomcat.通过nginx修改配置后reload ...

  7. 集群中几种session同步解决方案的比较

    1. 客户端cookie加密 .比较好的方法是自己采用cookie机制来实现一个session,在应用中使用此session实现. 问题:session中数据不能太多,最好只有个用户id. Sessi ...

  8. Tomcat中session共享问题的简单解决办法

    tomcat-redis-session-manager 使用redis配置tomcat共享session 结构图: 分析: 分布式web server集群部署后需要实现session共享,针对 to ...

  9. 了解负载均衡 会话保持 session同步(转)

    一,什么负载均衡 一个新网站是不要做负载均衡的,因为访问量不大,流量也不大,所以没有必要搞这些东西.但是随着网站访问量和流量的快速增长,单台服务器受自身硬件条件的限制,很难承受这么大的访问量.在这种情 ...

随机推荐

  1. 概率DP自学

    转自https://blog.csdn.net/zy691357966/article/details/46776199 zy691357966的blog 有关概率和期望问题的研究 摘要 在各类信息学 ...

  2. 【比赛】NOIP2018 旅行

    发现 \(m\) 只有两种取值,于是可做了 树的直接贪心 图的枚举环上的边去掉,然后做树的贪心,搜的时候剪一下枝吧 写得有点乱 #include<bits/stdc++.h> #defin ...

  3. 【BZOJ4408】[FJOI2016]神秘数(主席树)

    [BZOJ4408][FJOI2016]神秘数(主席树) 题面 BZOJ 洛谷 题解 考虑只有一次询问. 我们把所有数排个序,假设当前可以表示出的最大数是\(x\). 起始\(x=0\). 依次考虑接 ...

  4. [luogu2617][bzoj1901][Zju2112]Dynamic Rankings【树套树+树状数组+主席树】

    题目网址 [传送门] 题目大意 请你设计一个数据结构,支持单点修改,区间查询排名k. 感想(以下省略脏话inf个字) 真的强力吹爆洛谷数据,一般的树套树还给我T了一般的点,加强的待修主席树还给我卡了几 ...

  5. 【转】VMware 全屏显示

    首先解决一个问题:配置虚拟机,发现屏幕大小太小 需要安装vmware tools ,屏幕就会自适应 但是安装vmware tools 的按钮是灰的,所以我首先就是安装它     [来源]

  6. 【map】p1184 高手之在一起

    题目背景 高手是可以复活的,这点我们大家都知道. 题目描述 高手列出了一个详尽的日程表,这次他要追求的则是一个心灵纯洁的小萝莉.他和她都是要上课的,但是也会有时间空闲,于是高手决定无时无刻都要跟着她. ...

  7. Windows Update第三方工具概览

    受方程式黑客组织0Day攻击影响,所有的Windows服务器都要更新补丁. 方程式0day漏洞攻击介绍:https://zhuanlan.zhihu.com/p/26375989 腾讯云的解决方案:h ...

  8. UOJ#418. 【集训队作业2018】三角形

    #418. [集训队作业2018]三角形 和三角形没有关系 只要知道儿子放置的顺序,就可以直接模拟了 记录历史最大值 用一个pair(a,b):之后加上a个,期间最大值为增加b个 合并? A1+A2= ...

  9. 代码合并工具Beyond Compare的使用技巧

    使用技巧 文件合并 过滤 https://edi.wang/post/2013/2/17/using-beyond-compare 文件夹比较 http://www.beyondcompare.cc/ ...

  10. malloc() 和 calloc()有啥区别

    calloc()在动态分配完内存后,自动初始化该内存空间为零(会将所分配的内存空间中的每一位都初始化为零). 而malloc()不初始化,里边数据是随机的垃圾数据. calloc(size_t n, ...