apache tomcat session共享问题

骑士的崛起 2013-11-06 04:27:29
apache+3个tomcat6.0
最初我把3个tomcat放在一个机器上,session共享没问题。我把其中一个tomcat1打包放到另一个机器上后就有问题了,现象:第一次访问,tomcat1的sessionid为a,再次访问tomcat2的sessionid就变成b了,再次访问tomcat3的sessionid就还是b了,再次访问session变化顺序为cddeffhii...这样的循环变化,明显是tomcat1有问题,我的配置如下。
mod_jk.conf

LoadModule jk_module modules/mod_jk.so
JkWorkersFile conf/workers.properties
#指定那些请求交给tomcat处理(例如:*.jsp),"controller"为在workers.propertise里指定的负载分配控制器名
JkMount /*.jsp controller
JkMount /*.do controller
JkMount /*.jpg controller
JkMount /*.gif controller
JkMount /*.png controller
JkMount /*.htm controller
JkMount /*.html controller
JkMount /*.css controller
JkMount /*.js controller
JkMount /* controller

workers.properties

#server
worker.list = controller
#========tomcat1========
worker.tomcat1.port=8001
worker.tomcat1.host=192.168.1.160
worker.tomcat1.type=ajp13
worker.tomcat1.lbfactor = 1
#========tomcat2========
worker.tomcat2.port=8002
worker.tomcat2.host=localhost
worker.tomcat2.type=ajp13
worker.tomcat2.lbfactor = 1
#========tomcat3========
worker.tomcat3.port=8003
worker.tomcat3.host=localhost
worker.tomcat3.type=ajp13
worker.tomcat3.lbfactor = 1
#========controller,负载均衡控制器========
worker.controller.type=lb
worker.controller.balanced_workers=tomcat1,tomcat2,tomcat3
worker.controller.sticky_session=false
worker.controller.sticky_session_force=1
#worker.controller.sticky_session=1

tomcat server.xml 3个tomcat除了端口都一样,为写的部分都是默认的。

<Service name="Catalina">

<Connector port="8091" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8441" />
<Connector port="8001" protocol="AJP/1.3" redirectPort="8441" />

<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">


<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>

<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>

<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">

</Host>
</Engine>
</Service>

有人知道哪里问题吗?
...全文
1835 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_28295007 2016-07-14
  • 打赏
  • 举报
回复
骑士的崛起 2013-11-07
  • 打赏
  • 举报
回复
引用 8 楼 ldh911 的回复:
再看了下你的配置,你对 sticky_session 是强制false,那么请求不保证发回原服务。是你故意想测试是吧? 因为你本机的两个节点Session正常,只有剥离出去的不正常;看来问题可能出在Tomcat这边的Sesion复制,再检查下这块的配置看看。
确实为了测试,sticky_session设为true的情况我也测试了,关掉一个tomcat2后,会自动访问tomcat3,session复制也正常。 这个是剥离的tomcat1 server.xml完整信息,我剥离前后我没改过,不知道是什么问题。

<?xml version='1.0' encoding='utf-8'?>
<Server port="8051" shutdown="SHUTDOWN">
    <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on"/>
    <Listener className="org.apache.catalina.core.JasperListener"/>
    <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
    <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener"/>
    <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>

    <GlobalNamingResources>
        <Resource name="UserDatabase" auth="Container"
                  type="org.apache.catalina.UserDatabase"
                  description="User database that can be updated and saved"
                  factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
                  pathname="conf/tomcat-users.xml"/>
    </GlobalNamingResources>
    <Service name="Catalina">
        <Connector port="8091" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8441"/>

        <Connector port="8001" protocol="AJP/1.3" redirectPort="8441"/>
        <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">

            <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
            <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
                   resourceName="UserDatabase"/>

            <Host name="localhost" appBase="webapps"
                  unpackWARs="true" autoDeploy="true"
                  xmlValidation="false" xmlNamespaceAware="false">

            </Host>
        </Engine>
    </Service>
</Server>
  • 打赏
  • 举报
回复
引用 7 楼 zxcvbnm11920 的回复:
[quote=引用 3 楼 yetaodiao 的回复:]
哥们你发给我这堆东西也解决不了我的问题啊。。。让我结什么贴。[/quote]
MiceRice 2013-11-07
  • 打赏
  • 举报
回复
再看了下你的配置,你对 sticky_session 是强制false,那么请求不保证发回原服务。是你故意想测试是吧? 因为你本机的两个节点Session正常,只有剥离出去的不正常;看来问题可能出在Tomcat这边的Sesion复制,再检查下这块的配置看看。
骑士的崛起 2013-11-07
  • 打赏
  • 举报
回复
引用 3 楼 yetaodiao 的回复:
哥们你发给我这堆东西也解决不了我的问题啊。。。让我结什么贴。
骑士的崛起 2013-11-07
  • 打赏
  • 举报
回复
引用 5 楼 ldh911 的回复:
既然是把1移出去了了,重点检查 1 的 workers.properties 配置是否正确。
worker.tomcat1.port=8001 worker.tomcat1.host=192.168.1.160 worker.tomcat1.type=ajp13 worker.tomcat1.lbfactor = 1 我就把原来的worker.tomcat1.host=localhost变成worker.tomcat1.host=192.168.1.160,其他都没动过。
MiceRice 2013-11-07
  • 打赏
  • 举报
回复
既然是把1移出去了了,重点检查 1 的 workers.properties 配置是否正确。
MiceRice 2013-11-07
  • 打赏
  • 举报
回复
引用 15 楼 zxcvbnm11920 的回复:
我把我剥离的tomcat放到192.168.20.153的机器上果然没问题了。
直到看到12楼贴出来的日志信息,再加上前面把问题范围基本缩小到组播层面,才算是运气好发现这个问题。 祝顺利~~
骑士的崛起 2013-11-07
  • 打赏
  • 举报
回复
引用 14 楼 ldh911 的回复:
啊哦,突然发现你两台机器IP莫非分别是: 192, 168, 20, 165 和 192.168.1.160 ?! 这个跨域了。。。这下子就把组播复杂度提升一个等级。。。恐怕很难实现了。。。
知识面不够,完全没想到这个问题,大神果然没让我失望。 我把我剥离的tomcat放到192.168.20.153的机器上果然没问题了。 “花花我稀饭你 ”也是好人,都给分。
MiceRice 2013-11-07
  • 打赏
  • 举报
回复
啊哦,突然发现你两台机器IP莫非分别是: 192, 168, 20, 165 和 192.168.1.160 ?! 这个跨域了。。。这下子就把组播复杂度提升一个等级。。。恐怕很难实现了。。。
MiceRice 2013-11-07
  • 打赏
  • 举报
回复
228.0.0.4 不是常规IP地址,是组播地址;具体可以自己找找Wiki或Google。 这样的话,还需要检测下两台机器之间是否允许组播,有可能被机器上的防火墙或路由器安全策略拦截了两台机器之间的组播,以免发生网络风暴攻击;恐怕要写个小程序自己测测看你的网络环境里,是否跨机器能实现组播。 不知道Tomcat是否支持非组播的Session共享,这个如果有时间你Google下。
骑士的崛起 2013-11-07
  • 打赏
  • 举报
回复
引用 11 楼 ldh911 的回复:
咦?为什么没看到关于会话复制方面的配置,类似于: 上面这个就是以广播方式来实现会话复制。
我看http://www.iteye.com/topic/1017961这个人的配置弄的,他就写的 <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> 里面什么都没有,你写的这种我也试过了,还是本机放3个tomcat,session共享没问题,剥离就不行了,并且我的机器ping不通228.0.0.4。会不会端口问题呢?但启动没报错信息。 能共享的tomcat会有这些信息,不剥离的那个没有。

2013-11-7 14:08:01 org.apache.catalina.ha.tcp.SimpleTcpCluster memberAdded
信息: Replication member added:org.apache.catalina.tribes.membership.MemberImpl[tcp://{192, 168, 20, 165}:4000,{192, 168
, 20, 165},4000, alive=2020,id={67 -84 -45 -119 20 30 79 -39 -124 78 6 124 -13 -48 -124 -5 }, payload={}, command={}, do
main={}, ]
2013-11-7 14:08:02 org.apache.catalina.tribes.io.BufferPool getBufferPool
信息: Created a buffer pool with max size:104857600 bytes of type:org.apache.catalina.tribes.io.BufferPool15Impl
MiceRice 2013-11-07
  • 打赏
  • 举报
回复
咦?为什么没看到关于会话复制方面的配置,类似于:
<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"/>
...
上面这个就是以广播方式来实现会话复制。
骑士的崛起 2013-11-06
  • 打赏
  • 举报
回复
汗,谢谢帮顶。
  • 打赏
  • 举报
回复
  • 打赏
  • 举报
回复
如何在一个tomcat下的几个web应用之间共享session 我们采取的是集中管理的办法。主要技术: 1.设置Context 的crossContext="true",使得各个web应用的servletcontext是可以互访的 <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> <Context path="/SessionManager" reloadable="true" crossContext="true"></Context> <Context path="/SessionManagerTest1" reloadable="true" crossContext="true"></Context> <Context path="/SessionManagerTest2" reloadable="true" crossContext="true"></Context> 2.主动设置cookies,设置jsessionid为被共享的session的id,统一利用requestsessionid在指定的一个 servletcontext里的一个map查找对于的session,需要存取attribute都对取得的session操作 3.用监听器监听属性的失效 ============================================================================================ Tomcat集群之Session复制配置 分享 因为最近的项目要用到多web服务器实现访问负载和集群,负载调度使用的是LVS,而非apache的负载调度,因为在高访问量和大并发量的时候LVS的性能比APACHE好。然后在web服务器上是使用tomcat5.5.25做应用服务器,对于tomcat的集群有两种方式,这个主要是针对 session而言的。一种就是sticky模式,即黏性会话模式;另外一种就是session复制模式了。所谓sticky模式就是说同一个用户的访问请求都被派送到同一个tomcat实例上,这样我们就无须在多台服务器之间实现session共享了,这是其好处,不好的地方就是不能实现 failureover了,一但用户访问的机器挂掉,那么其session就会丢失。而session复制模式就可以很好的解决failureover的问题,即使某一台web服务器挂掉了,用户的请求还会被负载到其他的web服务器上,而且session也被复制了,这样对用户而言就像是在同一台机器上操作一样,不好的地方就是session复制需要系统资源和网络的开销,尤其是当web服务器多的时候或session里存储的数据量大的时候,这点将会比较的明显(不过自己还没有做这方面的测试)。 针对这两种方式的弊端和好处,我们可以采用将两种方式结合的方式来达到更好的效果,那就是sticky+session复制模式了。用户的请求按照 sticky方式被分发到同一个web服务器上,同时tomcat在后台做异步复制(非同步)session到其他web服务器,这样我们使用 sticky的简便性,同时又有了一定的容错能力。 下面我就将自己的tomcat集群配置经验跟大家分享一下,呵呵。现在想来,其实tomcat的集群配置真的是非常简单,几乎不需要改什么东西了。我今天就在windows上用一台机器来跑两个tomcat实例,下面是一些基础条件: 1.两个tomcat的目录分别为:d:\apache-tomcat-5.5.25-node1和d:\apache-tomcat-5.5.25-node2 2.在每个tomcat目录下的conf\Catalina\localhost目录下建立一个ROOT.xml文件,其内容为: 1 <?xml version="1.0" encoding="UTF-8"?> 2 <Context docBase="D:/mywebapps/test1" 3 privileged="true" antiResourceLocking="false" antiJARLocking="false" distributable="true"> 4 </Context> 3.修改apache-tomcat-5.5.25-node1的connector端口为8091,修改apache-tomcat-5.5.25-node2的connector的端口为8092,这样是为了避免在同一机器上同时启动时造成访问端口冲突; 4.修改apache-tomcat-5.5.25-node2的Server端口为8006,与apache-tomcat-5.5.25-node1的Server端口8005不一样,也是避免两个tomcat实例启动时造成程序端口的冲突问题; 5.修改apache-tomcat-5.5.25-node2的AJP/1.3的端口为8019或其他非8009(默认)的端口,也是为了避免与apache-tomcat-5.5.25-node1的AJP/1.3端口冲突; 这样,我们就可以保证每一个tomcat单独启动时都可以提供D:/mywebapps/test1的web服务,注意是单个启动哦,然后分别启动 apache-tomcat-5.5.25-node1和apache-tomcat-5.5.25-node2后,输入如下地址分别进行访问你的web 应用: apache-tomcat-5.5.25-node1的访问地址:http://localhost:8091/你的页面地址 apache-tomcat-5.5.25-node2的访问地址:http://localhost:8092/你的页面地址 如果你的tomcat没能成功的提供服务,那么你就需要查看一下是否tomcat部署成功了。注意这里的D:/mywebapps/test1就是你的web应用的物理路径了,可以随意修改。下面就开始对server.xml文件的配置了。 找到apache-tomcat-5.5.25-node1目录下的server.xml文件,打开并找到配置Engine的位置,我们在最后加入 jvmRoute="node1",表示这个tomcat的实例名称为node1。修改前后的对比如下: 修改前: <Engine name="Catalina" defaultHost="localhost"> 修改后: <Engine name="Catalina" defaultHost="localhost" jvmRoute="node1"> 然后找到Cluster标签,并取消它的注释即可,无须做任何修改。同样,我们修改apache-tomcat-5.5.25-node2下的 server.xml文件,修改jvmRoute="node2",然后也是注释掉Cluster标签,注意,然后还要修改Cluster标签下的 Receiver标签的tcpListenPort端口号,我们改为4002(默认的是4001),这个是为了避免两个tomcat实例同时启动时造成冲突。 通过上面的配置后,我们两个tomcat已经配置完毕,并且可以完成集群任务了。注意启动的时候不能直接双击其bing目录下的 startup.bat文件,我们还需要为每一个tomcat设置环境变量,分别在apache-tomcat-5.5.25-node1和 apache-tomcat- 5.5.25-node2的根目录下编写一个bat文件,内容如下: apache-tomcat-5.5.25-node1目录下的startup_node1.bat内容: set CATALINA_HOME=d:\apache-tomcat-5.5.25-node1 bin/startup.bat apache-tomcat-5.5.25-node2目录下的startup_node2.bat内容: set CATALINA_HOME=d:\apache-tomcat-5.5.25-node2 bin/startup.bat 然后分别运行这两批处理文件即可正常启动tomcat了。我们先启动node1,双击startup_node1.bat启动node1。我们可以在窗口的最上面看到如下的输出信息: 2008-1-4 19:12:24 org.apache.catalina.cluster.tcp.SimpleTcpCluster start 信息: Cluster is about to start 2008-1-4 19:12:25 org.apache.catalina.cluster.tcp.ReplicationTransmitter start 信息: Start ClusterSender at cluster Catalina:type=Cluster,host=localhost with n ame Catalina:type=ClusterSender,host=localhost 2008-1-4 19:12:25 org.apache.catalina.cluster.mcast.McastServiceImpl setupSocket 信息: Setting cluster mcast soTimeout to 500 2008-1-4 19:12:25 org.apache.catalina.cluster.mcast.McastService start 信息: Sleeping for 2000 milliseconds to establish cluster membership 2008-1-4 19:12:27 org.apache.catalina.cluster.mcast.McastService registerMBean 信息: membership mbean registered (Catalina:type=ClusterMembership,host=localhos t) 2008-1-4 19:12:27 org.apache.catalina.cluster.deploy.FarmWarDeployer start 信息: Cluster FarmWarDeployer started. 2008-1-4 19:12:29 org.apache.catalina.cluster.session.DeltaManager start 信息: Starting clustering manager...: 2008-1-4 19:12:29 org.apache.catalina.cluster.session.DeltaManager start 信息: Register manager to cluster element Host with name localhost 2008-1-4 19:12:29 org.apache.catalina.cluster.session.DeltaManager start 信息: Starting clustering manager at 2008-1-4 19:12:29 org.apache.catalina.cluster.session.DeltaManager getAllCluster Sessions 信息: Manager []: skipping state transfer. No members active in cluster group. 这表明我们的tomcat集群已经正常启动了。然后我们再运行apache-tomcat-5.5.25-node2目录下的startup_node2.bat以启动node2。然后我们可以可以在窗口的最上方看到如下的信息输出: 2008-1-4 19:16:32 org.apache.catalina.cluster.tcp.SimpleTcpCluster start 信息: Cluster is about to start 2008-1-4 19:16:32 org.apache.catalina.cluster.tcp.ReplicationTransmitter start 信息: Start ClusterSender at cluster Catalina:type=Cluster,host=localhost with n ame Catalina:type=ClusterSender,host=localhost 2008-1-4 19:16:32 org.apache.catalina.cluster.mcast.McastServiceImpl setupSocket 信息: Setting cluster mcast soTimeout to 500 2008-1-4 19:16:32 org.apache.catalina.cluster.mcast.McastService start 信息: Sleeping for 2000 milliseconds to establish cluster membership 2008-1-4 19:16:32 org.apache.catalina.cluster.tcp.SimpleTcpCluster memberAdded 信息: Replication member added:org.apache.catalina.cluster.mcast.McastMember[tcp ://192.168.1.227:4001,catalina,192.168.1.227,4001, alive=245203] 2008-1-4 19:16:34 org.apache.catalina.cluster.mcast.McastService registerMBean 信息: membership mbean registered (Catalina:type=ClusterMembership,host=localhos t) 2008-1-4 19:16:34 org.apache.catalina.cluster.deploy.FarmWarDeployer start 信息: Cluster FarmWarDeployer started. 2008-1-4 19:16:35 org.apache.catalina.cluster.session.DeltaManager start 信息: Starting clustering manager...: 2008-1-4 19:16:35 org.apache.catalina.cluster.session.DeltaManager start 信息: Register manager to cluster element Host with name localhost 2008-1-4 19:16:35 org.apache.catalina.cluster.session.DeltaManager start 信息: Starting clustering manager at 2008-1-4 19:16:35 org.apache.catalina.cluster.session.DeltaManager getAllCluster Sessions 警告: Manager [], requesting session state from org.apache.catalina.cluster.mcas t.McastMember[tcp://192.168.1.227:4001,catalina,192.168.1.227,4001, alive=248203 ]. This operation will timeout if no session state has been received within 60 s econds. 2008-1-4 19:16:35 org.apache.catalina.cluster.session.DeltaManager waitForSendAl lSessions 请注意node2窗口输出的不同颜色部分,这个已经表示node2节点和node2节点联系上了。我们再回过来看node1窗口的输出信息,发现多出了如下的信息: 2008-1-4 19:16:34 org.apache.catalina.cluster.tcp.SimpleTcpCluster memberAdded 信息: Replication member added:org.apache.catalina.cluster.mcast.McastMember[tcp ://192.168.1.227:4002,catalina,192.168.1.227,4002, alive=0] 这表明node1也已经侦听到了node2,两个tomcat服务器已经建立了联系。然后我们访问node1的一个地址A,假设这个地址A往 session里设置一个属性,然后我们再在同一窗口中访问node2的一个地址B,假设B是从session里读取这个属性,我们会发现B地址确实得到了这个刚刚我们在node1上设置进去的值。这里要特别注意的是,我们两个地址的分别访问必须是在同一个窗口中,因为我们没有做前端的web负载,所以使用不同的窗口进行访问会出现不同的session(因为端口号不一样,也就导致访问地址不一样了),这样就导致无法查看的问题。 ======================================================================================================= tomcat session共享配置 --配置session共享修改engine <Engine name="Catalina"defaultHost="localhost" jvmRoute="jvm2"> <ClusterclassName="org.apache.catalina.ha.tcp.SimpleTcpCluster"> <ManagerclassName="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/> <ChannelclassName="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" mcastTTL="1"/> <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="auto" port="4000" //不同tomcat端口配置不同 autoBind="0" selectorTimeout="100" maxThreads="6"/> <SenderclassName="org.apache.catalina.tribes.transport.ReplicationTransmitter"> <TransportclassName="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/> </Sender> <InterceptorclassName="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/> <InterceptorclassName="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/> </Channel> <ValveclassName="org.apache.catalina.ha.tcp.ReplicationValve" filter=".*\.gif;.*\.js;.*\.jpg;.*\.htm;.*\.html;.*\.txt;"/> <ClusterListenerclassName="org.apache.catalina.ha.session.ClusterSessionListener"/> </Cluster>

25,985

社区成员

发帖
与我相关
我的任务
社区描述
高性能WEB开发
社区管理员
  • 高性能WEB开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧