开发者社区> 问答> 正文

多个tomcat配置 cluster 使用组播方式共享session,会出现session丢失:报错

最近成功使用了 Nginx + 2 个tomcat7 在一台Linux机器上实现了负载均衡。

tomcat之间通过配置cluster + web.xml 配置 <distributable /> 实现 session复制功能,但是当在web系统中点击url访问功能,会时不时出现session丢失,要求重新登录。

通过chrome或firebug看拦截每个URL时的头部 cookie,可以看到 JSESSIONID = xxxxx.jvm1 和 JSESSIONID = xxxxx.jvm2 进行切换,这说明了 nginx 负载均衡有效,将http请求分发给2个tomcat进行处理,但是当访问了几次http(或 jvm1, jvm2切换几次)后,就出现了 session 丢失,JSESSIONID 值变了,不知道为什么了?

下面的2个tomcat的 cluster 配置:

tomcat:8080

<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="10.0.125.15"
                      port="4001"
                      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=""/>
          <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:9090

<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="10.0.125.15"
                      port="4002"
                      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=""/>
          <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>

说明:

1. linux 的组播服务是正常的:route add -net 224.0.0.0 netmask 240.0.0.0 dev eth1

2. 2个tomcat之间的tcp通信也是正常的,启动2个tomcat后,会在日志中看到类似的:

Manager [localhost#/crm], requesting session state from org...Memberlmpl[tcp://{10,0,125,15}:4002] ....

3. 当我停掉一个tomcat后,令一个tomcat的日志中就会显示:

Received member disappeared:org....MemberImlp[tcp://{10,0,125,15}:4001], ...., UDP Port=-1,.. id={-3 67....}...., command={66 65 66 89......}, domain={}

以上都说明了2个tomcat之间的集群通信都是OK的,但是为什么2个tomcat之间的session共享有时正常,有时不正常呢?时不时的 session 就丢失了。

请大家帮我看看啊,我的CRM项目中使用大量的iframe,有没有可能是 iframe 造成了2个tomcat之间session共享丢失呢?

 

 

 

 

展开
收起
kun坤 2020-06-20 11:29:57 1825 0
1 条回答
写回答
取消 提交回答
  • <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="10.0.125.15" port="4002" autoBind="100" selectorTimeout="5000" maxThreads="6"/>

    不知道楼主解决没? 我也是最近,集群出问题,我已知就是 集群之间的分发? 这个监听接收的

    address="10.0.125.15"

      看你这个ip 是否不对?  是静态ip ? 或者几个tomcat 不在同一台机器上? 写内网ip 应该就可以

    我的也是session 在第一次浏览打开后点了操作后,就丢失,不知道楼主后来解决没?



    ######我也是出现问题了,也是session变了,但是没有丢失。如果用代码用之前登录时用的session去访问是正常的,但是火狐接到的session变了,出现的原因也和你们不一样。我是在客户端快速点刷新,马上点停止,再刷新发现session变了,但是原来的session使用代码又可以用,证明session没有丢,但是服务端返回了另外一个sessionid
    ######tomcat配置
    <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"  channelSendOptions="6"> 
    			<Manager className="org.apache.catalina.ha.session.BackupManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true" mapSendOptions="6"/> 
    			<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="5001" selectorTimeout="100" 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"/> 
    				<Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/> 
    			</Channel> 
    			<Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/> 
    			<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.ClusterSessionListener"/> 
    		</Cluster>
    apache配置
    
    ProxyPass /images !
    ProxyPass /css ! 
    ProxyPass /js !
    ProxyPass /themes !
    
    ProxyRequests Off  
    ProxyPass /oa balancer://app/oa
    <Proxy balancer://app/>
    	BalancerMember ajp://127.0.0.1:8009 loadfactor=1 route=jvm1
    	BalancerMember ajp://127.0.0.1:8010 loadfactor=1 route=jvm2
    	BalancerMember ajp://127.0.0.1:8011 loadfactor=1 route=jvm3
    </Proxy>
    我做的也是session问题,登录的时候存在session的数据,页面跳转后就取不到了.######呵呵,终于搞定了,在web.xml中添加<distributable/>就可以了!######<distributable/>仅仅添加这个就好?######

    <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
    33                     tempDir="/tmp/war-temp/"
    34                     deployDir="/tmp/war-deploy/"
    35                     watchDir="/tmp/war-listen/"

    36                     watchEnabled="false"/>
    我想问这个是做什么的?

    ######

    引用来自“shilei990”的评论

    <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
    33                     tempDir="/tmp/war-temp/"
    34                     deployDir="/tmp/war-deploy/"
    35                     watchDir="/tmp/war-listen/"

    36                     watchEnabled="false"/>
    我想问这个是做什么的?

    tomcat7以后得一个新特性,farmwardeployer,在一台web server上部署应用后,其他web server可以通过监听指定的目录进行自动更新部署######我还碰到,同步超时后,重启tomcat的情况呢。tomcat7057,java1.7.0_67######

    请问解决了吗? 最近使用Nginx + tomcat(两台) session 复制也出现问题了

    三月 15, 2017 10:04:08 上午 org.apache.catalina.ha.session.ClusterSessionListener messageReceived
    警告: Context manager doesn't exist:localhost#

    情况跟你类似

    2020-06-20 11:30:08
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
Apache Tomcat 的云原生演进 立即下载
Data as a Service - 数据即服务 -- MongoDB⾼级应⽤模式 立即下载
《基于 Service Worker 实现在线代理》 立即下载