2

我目前正在搭建一个tomcat 6集群环境,liferay 6.0.6。具有会话复制的 4 个节点。没有粘性会话。

因此,按照本网站提供的指南,我执行了以下操作:

webapps/conf/context.xml 添加:webapps/ROOT/WEB-INF/web.xml 添加:到文件顶部,在第一个括号之后。我还向我的所有自定义 portlet web.xml 添加了 distributable。在 setenv.sh 中:-Djava.net.preferIPv6Addresses=false -Djava.net.preferIPv4Stack=true

在 webapps/conf/server.xml

<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcatA" />

跨节点的tomcatA/B/C/D。

<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.10" 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" timeout="30000" />
        </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;.*\.jpg;.*\.png;.*\.css;.*\.txt;" />
    <ClusterListener
        className="org.apache.catalina.ha.session.ClusterSessionListener" />
</Cluster>

在启动时,每个节点都会互相检测到,并且似乎可以正常工作。然而,当有人试图修改网页内容时,我们会得到一个错误:

SEVERE: Manager [localhost#/]: Unable to receive message through TCP channel
java.lang.IllegalStateException: setAttribute: Session already invalidated
    at org.apache.catalina.session.StandardSession.setAttribute(StandardSession.java:1326)
    at org.apache.catalina.ha.session.DeltaSession.setAttribute(DeltaSession.java:594)
    at org.apache.catalina.ha.session.DeltaRequest.execute(DeltaRequest.java:164)
    at org.apache.catalina.ha.session.DeltaManager.handleSESSION_DELTA(DeltaManager.java:1487)
    at org.apache.catalina.ha.session.DeltaManager.messageReceived(DeltaManager.java:1437)
    at org.apache.catalina.ha.session.DeltaManager.messageDataReceived(DeltaManager.java:1171)
    at org.apache.catalina.ha.session.ClusterSessionListener.messageReceived(ClusterSessionListener.java:92)
    at org.apache.catalina.ha.tcp.SimpleTcpCluster.messageReceived(SimpleTcpCluster.java:901)
    at org.apache.catalina.ha.tcp.SimpleTcpCluster.messageReceived(SimpleTcpCluster.java:882)
    at org.apache.catalina.tribes.group.GroupChannel.messageReceived(GroupChannel.java:269)
    at org.apache.catalina.tribes.group.ChannelInterceptorBase.messageReceived(ChannelInterceptorBase.java:79)
    at org.apache.catalina.tribes.group.interceptors.TcpFailureDetector.messageReceived(TcpFailureDetector.java:110)
    at org.apache.catalina.tribes.group.ChannelInterceptorBase.messageReceived(ChannelInterceptorBase.java:79)
    at org.apache.catalina.tribes.group.ChannelInterceptorBase.messageReceived(ChannelInterceptorBase.java:79)
        at org.apache.catalina.tribes.group.ChannelCoordinator.messageReceived(ChannelCoordinator.java:241)
    at org.apache.catalina.tribes.transport.ReceiverBase.messageDataReceived(ReceiverBase.java:225)
    at org.apache.catalina.tribes.transport.nio.NioReplicationTask.drainChannel(NioReplicationTask.java:188)
    at org.apache.catalina.tribes.transport.nio.NioReplicationTask.run(NioReplicationTask.java:91)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)

我的 liferay-ext.properties :

cluster.link.autodetect.address=www.google.com:80
lucene.replicate.write=true
cluster.link.enabled=true

net.sf.ehcache.configurationResourceName=/cache/hibernate-clustered.xml
ehcache.multi.vm.config.location=/cache/liferay-multi-vm-clustered.xml

我还在所有节点上创建了一个 jsp

<td>
  Session ID</td>
<td><%= session.getId() %></td>
<% session.setAttribute("abc","abc"); %>
</tr>
<tr>
<td>
  Created on</td>
  <td><%= new java.util.Date(session.getCreationTime()).toString() %></td>
</tr>
</table>
</body>
</html>

使用同一个用户,我可以切换服务器,并且会话似乎可以毫无问题地复制。但是,当我在 liferay 中修改某些内容时,我仍然会得到堆栈跟踪。

我已经被困了一段时间了。我们检查了所有服务器和 JVM 时间是否与 NTP 服务器正确同步。没有端口被阻塞。服务器无法访问互联网。它们都在VM上运行。

有人知道我做错了什么吗?

谢谢你。

4

1 回答 1

7

一些笔记...

1.) 您报告的问题可能与用于channelSendOptions的值有关。

严重:管理器 [localhost#/]:无法通过 TCP 通道接收消息 java.lang.IllegalStateException:setAttribute:会话已失效

您当前的配置将channelSendOptions设置为值8。这意味着在您的节点之间发送的消息是异步发送的。这对速度很有好处,但是,这意味着数据可能会乱序到达 [1]。

错误消息表明它收到了更新会话属性的消息,但是要更新的会话已经失效(即删除)。出现此错误的一个常见原因是收到的消息乱序。

在大多数情况下,您可以通过将channelSendOptions设置为6来纠正此问题。这将同步发送消息,从而保证顺序。

[1] - https://tomcat.apache.org/tomcat-6.0-doc/config/cluster.html#Attributes

2.) 另一种可能性(虽然可能性较小)是您在 Tomcat 中遇到了错误。您没有列出您正在使用的 Tomcat 的具体版本,但升级到最新的 Tomcat 6.0.x 版本也是一个好主意。

3.)您表示“没有粘性会话就无法复制会话”。这是不正确的。会话复制和会话粘性是两个独立的过程。虽然它们经常一起使用,但会话复制不需要粘性会话,粘性会话不需要会话复制。

会话复制(Tomcat 称为“集群”)是跨多个 Tomcat 服务器复制会话数据的过程。当会话数据跨多个节点复制时,用户的请求发送到哪个节点并不重要,因为它们都具有相同的会话数据。

会话“粘性”由负载均衡器执行,它是负载均衡器的过程,可确保始终将一个会话定向到同一后端 Tomcat 服务器。

例如,负载平衡器将请求定向到 Tomcat 服务器 A,并且该请求会导致创建会话。启用会话粘性后,负载均衡器将向 Tomcat 服务器 A 发送具有相同会话 id 的每个附加请求。其他请求,没有会话或具有不同会话,将继续正常进行负载均衡。

像巧克力和花生酱一样,粘性会话和会话复制经常一起使用,但这不是必需的。只能使用粘性会话执行基本负载平衡,但是如果后端 Tomcat 节点发生故障,用户将丢失会话数据。通过会话复制和粘性会话,用户不会受到后端 Tomcat 节点之一故障的影响。它们将由负载平衡器自动路由到不同的节点,并且该节点将拥有用户会话数据的副本。

于 2012-11-01T14:48:50.917 回答