2

私は現在、Tomcat6クラスター環境であるliferay6.0.6をセットアップ中です。セッションレプリケーションを備えた4つのノード。スティッキーセッションはありません。

したがって、このサイトで提供されているガイドに従って、私は次のことを行いました:

webapps / conf / context.xmlが追加されました:webapps / ROOT / WEB-INF / web.xmlが追加されました:ファイルの先頭の最初の角かっこの後。また、すべてのカスタムポートレットweb.xmlに配布可能ファイルを追加しました。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>

起動時に各ノードがお互いを検出し、動作しているようです。ただし、誰かがWebコンテンツを変更しようとすると、エラーが発生します。

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の特定のバージョンをリストしていませんが、最新のTomcat6.0.xバージョンにアップグレードすることもお勧めします。

3.)「スティッキーセッションなしではセッションを複製できない」と指定しました。これは正しくありません。セッションレプリケーションとセッションスティッキネスは、2つの別個のプロセスです。それらはしばしば一緒に使用されますが、セッションレプリケーションはスティッキーセッションを必要とせず、スティッキーセッションはセッションレプリケーションを必要としません。

セッションレプリケーション(Tomcatでは「クラスタリング」と呼ばれます)は、複数のTomcatサーバー間でセッションデータをレプリケートするプロセスです。セッションデータが複数のノードに複製される場合、それらはすべて同じセッションデータを持っているため、ユーザーのリクエストがどのノードに送信されるかは問題ではありません。

セッションの「スティッキネス」はロードバランサーによって実行され、1つのセッションが常に同じバックエンドTomcatサーバーに送信されることを保証するロードバランサーのプロセスです。

たとえば、ロードバランサーが要求をTomcatサーバーAに送信すると、その要求によってセッションが作成されます。セッションスティッキネスを有効にすると、ロードバランサーは同じセッションIDを持つすべての追加リクエストをTomcatサーバーAに送信します。セッションがない、またはセッションが異なる他のリクエストは、引き続き通常どおりロードバランシングされます。

チョコレートとピーナッツバターのように、スティッキーセッションとセッション複製はしばしば一緒に使用されますが、それは必須ではありません。基本的な負荷分散はスティッキーセッションのみで実行できますが、バックエンドのTomcatノードで障害が発生した場合、ユーザーはセッションデータを失います。セッションレプリケーションとスティッキーセッションの両方で、ユーザーはバックエンドTomcatノードの1つで障害の影響を受けません。それらはロードバランサーによって自動的に別のノードにルーティングされ、そのノードにはユーザーのセッションデータのコピーがあります。

于 2012-11-01T14:48:50.917 に答える