[英]Tomcat session replication issue
TL; DR - 当主节点关闭时,sessionId中的节点名称未更新为备份中的当前节点名称。
Tomcat版本 - apache-tomcat-7.0.50
我设置了两个节点(我的应用程序在2个单独的tomcats中的2个实例),使用会话复制配置(也使用粘性会话).Below是来自server.xml的集群配置,它位于Engine标签内。 它在两个节点中都类似,但端口号除外:
<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="4050"
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"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>\
</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管理器中,我可以看到在登录时在主节点中创建了会话(例如:D042A0C5E380EB9E500224C87233119C.myNode1),并在备份中正确复制。
但是,一旦主节点出现故障,我希望备份节点中的sessionId能够使用当前节点名更新,即:D042A0C5E380EB9E500224C87233119C.myNode2
示例:
用户登录时:
Node 1 - Primary - jsessionIdSample.node1
Node 2 - Backup - jsessionIdSample.node1
当一个节点1发生故障时(预期) :
Node 1 - - jsessionIdSample.node1 (NODE GOES DOWN)
Node 2 - Primary - jsessionIdSample.node2
但是发生了什么:
Node 1 - - jsessionIdSample.node1 (NODE DOWN)
Node 2 - Backup - jsessionIdSample.node1
我有两个问题:
1)我的理解是,在主节点发生故障后,应该在备份中更新sessionID吗? 我读了tomcat文档,它似乎应该。
2)如果它应该,你能帮我配置这个工作吗? 我已经尝试过关于SO的其他问题的解决方案,但它们似乎都没有用。
编辑:根据建议添加完整的引擎配置:
节点1
<Engine name="Catalina" defaultHost="localhost" jvmRoute="node1">
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster">
<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="228.0.0.4"
port="4005"
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>
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
节点2
<Engine name="Catalina" defaultHost="localhost" jvmRoute="node2">
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster">
<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="228.0.0.4"
port="4010"
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>
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
提前致谢!
不确定你是否混淆了一些东西 - 比如你说
用户登录时:
Node 1 - Primary - jsessionIdSample.node1 Node 2 - Backup - jsessionIdSample.node1
节点2不应该使用以.node2结尾的会话ID吗?
使用IMHO的会话ID来自<Engine>
的jvmRoute
属性并且粘在机器上 - 当节点1配置了<Engine jvmRoute="node1">
,这就是节点1所知道的。 很遗憾,您没有引用上面的引擎配置。
jvmRoute只是对负载均衡器的一个提示,即哪台机器要路由,因此它必须稳定可靠。 它可能非常简单,可以额外确保您的Node 2配置了jvmRoute="node2"
。 我从未在tomcat中看到过任何不同的行为。
即使你对问题的更新后我感觉有些奇怪 - 请参阅我的答案中的引用部分,其中节点1和节点2都使用“node1”作为指标。 那可能是罪魁祸首(或者是一个被遗忘的错字)。 如果您使用Apache httpd,那么工作者必须像他们在workers.properties中的名字一样命名(至少它们必须是唯一的。请参阅https://tomcat.apache.org/connectors-doc/reference/workers .html )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.