博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
tomcat cluster session同步时保存map数据遇到的问题
阅读量:5113 次
发布时间:2019-06-13

本文共 2574 字,大约阅读时间需要 8 分钟。

Tomcat Cluster官网:(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
map = new HashMap
();map.put("email", "12345");req.getSession().setAttribute(Constants.KEY_SESSION_MAP, map);

 

问题:

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

Map
map = (Map
) req.getSession().getAttribute(Constants.KEY_SESSION_MAP);map.put("email", "67890");

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

Map
map = (Map
) 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数据。

详见: Cluster Information
Tomcat集群配置:

  
  
    
    
    
       
    
    
    
  
  
  
  
  
  

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

@Overridepublic 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
map = (Map
) 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发生变化(通过保存或删除数据)时才进行同步,减少不必要的集群同步消息。

 

 

转载于:https://www.cnblogs.com/nuccch/p/6832528.html

你可能感兴趣的文章
提高码力专题(未完待续)
查看>>
IOS第17天(3,Quartz2D画板和画线)
查看>>
pair的例子
查看>>
前端框架性能对比
查看>>
@property中 retain 详解
查看>>
java8 stream初试,map排序,list去重,统计重复元素个数,获取map的key集合和value集合...
查看>>
Python爬虫个人记录(四)利用Python在豆瓣上写一篇日记
查看>>
jdk8 Function
查看>>
第二次作业
查看>>
迷茫中的自己
查看>>
burp suite 的intruder 四种攻击方式
查看>>
机器学习----人脸对齐的算法-ASM.AAM..CLM.SDM
查看>>
自定义文本选中样式
查看>>
python3 字符串/列表/元组(str/list/tuple)相互转换方法及join()函数的使用
查看>>
MySQL 数据库 的安装和基本管理
查看>>
MyEclipse中JavaMail冲突问题
查看>>
四边形面积探索
查看>>
曾有一个人,爱我如生命(2)
查看>>
POJ3264
查看>>
日常记录
查看>>