設定リファレンスドキュメントも参照できます。
クラスタリング/セッションレプリケーション How-To
重要な注意事項
目次
急いでいる方へ
<Engine>
または<Host>
要素に
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
を追加してクラスタリングを有効にします。
上記の設定を使用すると、DeltaManager
を使用してセッションのデルタを複製するオールツーオールのセッションレプリケーションが有効になります。オールツーオールとは、すべてのセッションがクラスタ内の他のすべてのノードに複製されることを意味します。これは小規模なクラスタでは非常に効果的ですが、4ノードを超えるような大規模なクラスタにはお勧めしません。また、DeltaManager
を使用する場合、Tomcatはアプリケーションがデプロイされていないノードも含めて、すべてのノードにセッションを複製します。
これらの問題を回避するには、BackupManager
を使用します。BackupManager
はセッションデータをバックアップノードの1つにのみ、そしてアプリケーションがデプロイされているノードのみに複製します。DeltaManager
を使用してシンプルなクラスタを実行したら、クラスタ内のノード数を増やすにつれて、BackupManager
に移行することをお勧めします。
重要なデフォルト値をいくつか示します。
- マルチキャストアドレスは228.0.0.4です。
- マルチキャストポートは45564です(ポートとアドレスを合わせてクラスタメンバーシップを決定します)。
- ブロードキャストされるIPアドレスは
java.net.InetAddress.getLocalHost().getHostAddress()
です(127.0.0.1をブロードキャストしないようにしてください。これはよくある間違いです)。 - レプリケーションメッセージを待ち受けるTCPポートは、4000〜4100の範囲内の最初の使用可能なサーバーソケットです。
- リスナーは
ClusterSessionListener
として設定されています。 - 2つのインターセプター
TcpFailureDetector
とMessageDispatchInterceptor
が設定されています。
デフォルトのクラスタ設定を以下に示します。
<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="4000"
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.MessageDispatchInterceptor"/>
</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.ClusterSessionListener"/>
</Cluster>
このセクションについては、このドキュメントの後半で詳しく説明します。
セキュリティ
クラスタの実装は、すべてのクラスタ関連ネットワークトラフィックに安全で信頼できるネットワークが使用されていることを前提として記述されています。安全でない、信頼できないネットワークでクラスタを実行することは安全ではありません。
Tomcatクラスタで使用するための安全で信頼できるネットワークを提供するためのオプションは多数あります。これらには以下が含まれます。
- プライベートLAN
- 仮想プライベートネットワーク(VPN)
- IPSEC
EncryptInterceptorは、機密性と整合性保護を提供しますが、信頼できないネットワークでTomcatクラスタを実行すること、特にDoS攻撃に関連するすべてのリスクから保護するものではありません。
クラスタの基本
Tomcat 10コンテナでセッションレプリケーションを実行するには、次の手順を実行する必要があります。
- すべてのセッション属性は
java.io.Serializable
を実装する必要があります。 server.xml
のCluster
要素のコメントを外します。- カスタムクラスタバルブを定義している場合、
server.xml
のCluster要素の下にReplicationValve
も定義されていることを確認してください。 - Tomcatインスタンスが同じマシンで実行されている場合、各インスタンスの
Receiver.port
属性がユニークであることを確認してください。ほとんどの場合、Tomcatは4000〜4100の範囲で使用可能なポートを自動検出することで、これを独自に解決できます。 web.xml
に<distributable/>
要素があることを確認してください。- mod_jkを使用している場合、Engineに
<Engine name="Catalina" jvmRoute="node01" >
でjvmRoute属性が設定され、jvmRoute属性値がworkers.propertiesのワーカー名と一致していることを確認してください。 - すべてのノードの時刻が同じで、NTPサービスと同期していることを確認してください!
- ロードバランサーがスティッキーセッションモードに設定されていることを確認してください。
ロードバランシングは、「ロードバランシング」の章で説明されているように、多くの手法で実現できます。
注:セッション状態はCookieによって追跡されるため、外部から見たURLが同じでなければ、新しいセッションが作成されます。
ClusterモジュールはTomcat JULIロギングフレームワークを使用するため、通常のlogging.propertiesファイルを使用してロギングを設定できます。メッセージを追跡するには、キーorg.apache.catalina.tribes.MESSAGES
のロギングを有効にすることができます。
概要
Tomcatでセッションレプリケーションを有効にするには、まったく同じことを実現するために3つの異なる方法があります。
- セッションの永続化を使用し、セッションを共有ファイルシステムに保存する(PersistenceManager + FileStore)
- セッションの永続化を使用し、セッションを共有データベースに保存する(PersistenceManager + JDBCStore)
- Tomcatに付属のSimpleTcpCluster(lib/catalina-tribes.jar + lib/catalina-ha.jar)を使用して、インメモリレプリケーションを使用する
Tomcatは、DeltaManager
を使用してセッション状態のオールツーオールレプリケーションを実行するか、BackupManager
を使用して1つのノードのみにバックアップレプリケーションを実行できます。オールツーオールレプリケーションは、クラスタが小さい場合にのみ効率的なアルゴリズムです。大規模なクラスタの場合は、プライマリセカンダリのセッションレプリケーション戦略を使用するBackupManagerを使用する必要があります。この戦略では、セッションは1つのバックアップノードのみに保存されます。
現在、ドメインワーカー属性(mod_jk > 1.2.8)を使用してクラスタパーティションを構築し、DeltaManagerでよりスケーラブルなクラスタソリューションを実現できます(これにはドメインインターセプターを設定する必要があります)。オールツーオール環境でのネットワークトラフィックを削減するために、クラスタを小さなグループに分割できます。これは、異なるグループに異なるマルチキャストアドレスを使用することで簡単に実現できます。非常に簡単な設定は次のようになります。
DNS Round Robin
|
Load Balancer
/ \
Cluster1 Cluster2
/ \ / \
Tomcat1 Tomcat2 Tomcat3 Tomcat4
ここで重要なのは、セッションレプリケーションはクラスタリングの始まりに過ぎないということです。クラスタを実装するために使用されるもう1つの一般的な概念はファームであり、つまり、アプリケーションを1つのサーバーのみにデプロイし、クラスタ全体でデプロイメントを分散します。これらはすべて、FarmWarDeployer(server.xml
のクラスタ例を参照)で使用できる機能です。
次のセクションでは、セッションレプリケーションの動作と設定方法について詳しく説明します。
クラスタ情報
メンバーシップはマルチキャストハートビートを使用して確立されます。したがって、クラスタを細分化したい場合は、<Membership>
要素のマルチキャストIPアドレスまたはポートを変更することで実行できます。
ハートビートには、TomcatノードのIPアドレスと、TomcatがレプリケーショントラフィックをリッスンするTCPポートが含まれています。すべてのデータ通信はTCPを介して行われます。
ReplicationValve
は、リクエストが完了した時点を検出し、レプリケーションを開始するために使用されます(もしあれば)。セッションが変更された場合(セッションに対してsetAttributeまたはremoveAttributeを呼び出す場合)のみ、データが複製されます。
最も重要なパフォーマンス上の考慮事項の1つは、同期レプリケーションと非同期レプリケーションです。同期レプリケーションモードでは、複製されたセッションがワイヤを介して送信され、他のすべてのクラスタノードで再インスタンス化されるまで、リクエストは返されません。同期と非同期はchannelSendOptions
フラグを使用して設定され、整数値です。SimpleTcpCluster/DeltaManager
の組み合わせのデフォルト値は8(非同期)です。さまざまなchannelSendOptions
値の詳細については、設定リファレンスを参照してください。
便宜上、channelSendOptions
は整数ではなく名前で設定できます。名前は、起動時に整数値に変換されます。有効なオプション名は、「asynchronous」(エイリアス「async」)、「byte_message」(エイリアス「byte」)、「multicast」、「secure」、「synchronized_ack」(エイリアス「sync」)、「udp」、「use_ack」です。複数の名前を区切るにはカンマを使用します。たとえば、「async, multicast」を渡すと、オプションSEND_OPTIONS_ASYNCHRONOUS | SEND_OPTIONS_MULTICAST
になります。
送信フラグ(概要)または送信フラグ(Javadoc)で詳細を読むことができます。非同期レプリケーションでは、データが複製される前にリクエストが返されます。非同期レプリケーションによりリクエスト時間が短縮され、同期レプリケーションにより、リクエストが返される前にセッションが複製されることが保証されます。
クラッシュ後にフェイルオーバーノードにセッションをバインドする
mod_jkを使用していて、スティッキーセッションを使用していない場合、または何らかの理由でスティッキーセッションが機能しない場合、または単にフェイルオーバーしている場合、セッションIDは変更する必要があります。これは、以前は前のTomcatのワーカーID(Engine要素のjvmRouteで定義)が含まれていたためです。これを解決するために、JvmRouteBinderValveを使用します。
JvmRouteBinderValveはセッションIDを書き換え、フェイルオーバー後も次のリクエストがスティッキーな状態を維持することを保証します(ワーカーが使用できなくなったため、ランダムなノードにフォールバックしません)。このバルブは、Cookie内のJSESSIONID値を同じ名前で書き換えます。このバルブがないと、mod_jkモジュールの場合、障害発生時のスティッキネスを保証することが困難になります。
server.xml
に独自のバルブを追加する場合は、デフォルトが無効になるため、デフォルトで定義されているすべての適切なバルブを追加してください。
ヒント
属性sessionIdAttributeを使用して、古いセッションIDが含まれるリクエスト属性名を変更できます。デフォルトの属性名はorg.apache.catalina.ha.session.JvmRouteOriginalSessionIDです。
コツ
ノードを削除する前に、JMXを使用してこのmod_jkターンオーバーモードをすべてのバックアップノードで有効にすることができます!すべてのJvmRouteBinderValveバックアップでenableをtrueに設定し、mod_jkでワーカーを無効にしてから、ノードを削除して再起動します!その後、mod_jkワーカーを有効にし、JvmRouteBinderValvesを再度無効にします。このユースケースは、要求されたセッションのみが移行されることを意味します。
設定例
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
channelSendOptions="6">
<Manager className="org.apache.catalina.ha.session.BackupManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"
mapSendOptions="6"/>
<!--
<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="5000"
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.MessageDispatchInterceptor"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=".*\.gif|.*\.js|.*\.jpeg|.*\.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>
詳細に分解する!!
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
channelSendOptions="6">
この要素内には、すべてのクラスタの詳細を設定できます。channelSendOptions
は、SimpleTcpClusterクラスまたはSimpleTcpCluster.sendメソッドを呼び出すオブジェクトによって送信される各メッセージに添付されるフラグです。送信フラグの説明は、Javadocサイトをご覧ください。DeltaManager
はSimpleTcpCluster.sendメソッドを使用して情報を送信しますが、バックアップマネージャはチャネルを介して直接送信します。
詳細については、参考ドキュメントをご覧ください。
<Manager className="org.apache.catalina.ha.session.BackupManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"
mapSendOptions="6"/>
<!--
<Manager className="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"/>
-->
これは、`
詳細については、参考ドキュメントをご覧ください。
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
チャネル要素はTribesであり、Tomcatで使用されるグループ通信フレームワークです。この要素は、通信とメンバーシップロジックに関するすべてをカプセル化します。
詳細については、参考ドキュメントをご覧ください。
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="228.0.0.4"
port="45564"
frequency="500"
dropTime="3000"/>
メンバーシップはマルチキャストを使用して行われます。マルチキャストを超えるポイントにメンバーシップを拡張したい場合は、TribesはStaticMembershipInterceptor
を使用した静的メンバーシップもサポートすることに注意してください。address属性は使用されるマルチキャストアドレスであり、portはマルチキャストポートです。これら2つを組み合わせることで、クラスタの分離が実現されます。QAクラスタと本番クラスタが必要な場合は、QAクラスタを本番クラスタとは異なるマルチキャストアドレス/ポートの組み合わせにするのが最も簡単な構成です。
メンバーシップコンポーネントは、ノード間の通信がTCPを介して行えるように、自身のTCPアドレス/ポートを他のノードにブロードキャストします。ブロードキャストされるアドレスはReceiver.address
属性のアドレスであることに注意してください。
詳細については、参考ドキュメントをご覧ください。
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto"
port="5000"
selectorTimeout="100"
maxThreads="6"/>
Tribesでは、データの送受信ロジックが2つの機能コンポーネントに分割されています。名前が示すように、Receiverはメッセージの受信を担当します。Tribesスタックはスレッドレスであるため(現在他のフレームワークでも採用されている一般的な改善点)、このコンポーネントには、maxThreadsとminThreadsの設定を持つスレッドプールがあります。
address属性は、メンバーシップコンポーネントによって他のノードにブロードキャストされるホストアドレスです。
詳細については、参考ドキュメントをご覧ください。
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
</Sender>
Senderコンポーネントは、名前が示すように、他のノードへのメッセージ送信を担当します。SenderにはReplicationTransmitter
というシェルコンポーネントがありますが、実際の処理はサブコンポーネントTransport
で行われます。TribesはSenderのプールを持つことをサポートしているため、メッセージを並列に送信できます。NIO Senderを使用している場合は、メッセージを同時に送信することもできます。
同時とは、複数のSenderに同時に1つのメッセージを送信することを意味し、並列とは、複数のSenderに同時に複数のメッセージを送信することを意味します。
詳細については、参考ドキュメントをご覧ください。
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>
</Channel>
Tribesは、メッセージを送信するためにスタックを使用します。スタックの各要素はインターセプタと呼ばれ、Tomcatサーブレットコンテナのバルブと同様に機能します。インターセプタを使用すると、ロジックをより管理しやすいコードの断片に分割できます。上記で構成されたインターセプタは次のとおりです。
TcpFailureDetector - TCPを介してクラッシュしたメンバーを検証します。マルチキャストパケットがドロップされた場合、このインターセプタは誤検知を防ぎます(つまり、ノードはまだ稼働しているにもかかわらず、クラッシュしたとマークされます)。
MessageDispatchInterceptor - メッセージをスレッド(スレッドプール)にディスパッチして、非同期的にメッセージを送信します。
ThroughputInterceptor - メッセージトラフィックに関する簡単な統計情報を表示します。
インターセプタの順序は重要であることに注意してください。server.xmlで定義されている順序が、チャネルスタックで表される順序です。これを、ヘッドが最初のインターセプタで、テールが最後のインターセプタであるリンクリストと考えてください。
詳細については、参考ドキュメントをご覧ください。
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=".*\.gif|.*\.js|.*\.jpeg|.*\.jpg|.*\.png|.*\.htm|.*\.html|.*\.css|.*\.txt"/>
クラスタはバルブを使用してWebアプリケーションへのリクエストを追跡します。上記ではReplicationValveとJvmRouteBinderValveについて説明しました。`
詳細については、参考ドキュメントをご覧ください。
<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
デフォルトのTomcatクラスタはファームドデプロイメントをサポートしています。つまり、クラスタは他のノードにアプリケーションをデプロイおよびアンデプロイできます。このコンポーネントの状態は現在変動していますが、すぐに対応されます。Tomcat 5.0と5.5の間でデプロイメントアルゴリズムに変更があり、その時点でこのコンポーネントのロジックが変更され、デプロイディレクトリがwebappsディレクトリと一致する必要があります。
詳細については、参考ドキュメントをご覧ください。
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
SimpleTcpCluster自体はChannelオブジェクトのSenderとReceiverであるため、コンポーネントはSimpleTcpClusterにリスナーとして自身を登録できます。上記のリスナーClusterSessionListener
はDeltaManagerレプリケーションメッセージをリスンし、デルタをマネージャに適用します。マネージャはそれをセッションに適用します。
詳細については、参考ドキュメントをご覧ください。
クラスタアーキテクチャ
コンポーネントレベル
Server
|
Service
|
Engine
| \
| --- Cluster --*
|
Host
|
------
/ \
Cluster Context(1-N)
| \
| -- Manager
| \
| -- DeltaManager
| -- BackupManager
|
---------------------------
| \
Channel \
----------------------------- \
| \
Interceptor_1 .. \
| \
Interceptor_N \
----------------------------- \
| | | \
Receiver Sender Membership \
-- Valve
| \
| -- ReplicationValve
| -- JvmRouteBinderValve
|
-- LifecycleListener
|
-- ClusterListener
| \
| -- ClusterSessionListener
|
-- Deployer
\
-- FarmWarDeployer
動作原理
クラスタリングの仕組みを理解しやすくするために、いくつかのシナリオについて説明します。このシナリオでは、TomcatA
とTomcatB
の2つのTomcatインスタンスのみを使用することを計画しています。次のイベントシーケンスについて説明します。
TomcatA
が起動します。TomcatB
が起動します(TomcatA
の起動が完了するのを待ちます)。TomcatA
がリクエストを受信し、セッションS1
が作成されます。TomcatA
がクラッシュします。TomcatB
がセッションS1
のリクエストを受信します。TomcatA
が起動します。TomcatA
がリクエストを受信し、セッション(S1
)に対して無効化が呼び出されます。TomcatB
が新しいセッション(S2
)のリクエストを受信します。TomcatA
で、セッションS2
が非アクティブのために期限切れになります。
さて、良いシーケンスができたので、セッションレプリケーションコードで実際に何が起こるかを説明します。
TomcatA
が起動します。Tomcatは標準的な起動シーケンスを使用して起動します。Hostオブジェクトが作成されると、クラスタオブジェクトがそれに関連付けられます。コンテキストが解析されると、web.xmlファイルにdistributable要素が存在する場合、Tomcatはクラスタクラス(この場合は
SimpleTcpCluster
)に、レプリケートされたコンテキストのマネージャの作成を要求します。したがって、クラスタリングが有効になり、web.xmlにdistributableが設定されていると、TomcatはStandardManager
ではなく、そのコンテキストにDeltaManager
を作成します。クラスタクラスは、メンバーシップサービス(マルチキャスト)とレプリケーションサービス(TCPユニキャスト)を起動します。このドキュメントのさらに下にあるアーキテクチャの詳細については、後で説明します。TomcatB
が起動します。TomcatB
が起動すると、1つの例外を除いて、TomcatA
と同じシーケンスに従います。クラスタが起動し、メンバーシップ(TomcatA
、TomcatB
)が確立されます。TomcatB
は、クラスタに既に存在するサーバー(この場合はTomcatA
)からセッションの状態を要求します。TomcatA
はリクエストに応答し、TomcatB
がHTTPリクエストのリスンを開始する前に、状態がTomcatA
からTomcatB
に転送されます。TomcatA
が応答しない場合、TomcatB
は60秒後にタイムアウトし、ログエントリを出力して起動を続けます。セッションの状態は、web.xmlにdistributableがある各Webアプリケーションについて転送されます。(注:セッションレプリケーションを効率的に使用するには、すべてのTomcatインスタンスを同じように構成する必要があります)。TomcatA
がリクエストを受信し、セッションS1
が作成されます。TomcatA
に入ってきたリクエストは、セッションレプリケーションがない場合とまったく同じように処理されます。リクエストが完了するまで、その時点でReplicationValve
がレスポンスがユーザーに返される前にリクエストをインターセプトします。この時点で、セッションが変更されたことが判明し、TCPを使用してセッションをTomcatB
にレプリケートします。シリアル化されたデータがオペレーティングシステムのTCPロジックに渡されると、リクエストはバルブパイプラインを介してユーザーに戻ります。各リクエストに対してセッション全体がレプリケートされるため、setAttributeまたはremoveAttributeを呼び出さずにセッション内の属性を変更するコードもレプリケートされます。useDirtyFlag構成パラメータを使用して、セッションがレプリケートされる回数を最適化できます。TomcatA
がクラッシュします。TomcatA
がクラッシュすると、TomcatB
はTomcatA
がクラスタから脱落したことを通知されます。TomcatB
はメンバーシップリストからTomcatA
を削除し、TomcatA
にはTomcatB
で発生する変更は通知されなくなります。ロードバランサはTomcatA
からのリクエストをTomcatB
にリダイレクトし、すべてのセッションは最新の状態になります。TomcatB
がセッションS1
のリクエストを受信します。特に何もありません。
TomcatB
はリクエストを他のリクエストと同じように処理します。TomcatA
が起動します。起動時に、
TomcatA
が新しいリクエストを受け入れ、利用可能になる前に、上記1)2)で説明した起動シーケンスに従います。クラスタに参加し、TomcatB
にすべてのセッションの現在の状態を要求します。セッションの状態を受信すると、ロードが完了し、HTTP/mod_jkポートが開きます。したがって、TomcatB
からセッションの状態を受信するまで、TomcatA
にリクエストは届きません。TomcatA
がリクエストを受信し、セッション(S1
)に対して無効化が呼び出されます。無効化呼び出しがインターセプトされ、セッションが無効化されたセッションにキューイングされます。リクエストが完了すると、変更されたセッションを送信する代わりに、
TomcatB
に「期限切れ」メッセージを送信し、TomcatB
もセッションを無効化します。TomcatB
が新しいセッション(S2
)のリクエストを受信します。ステップ3)と同じシナリオです。
TomcatA
で、セッションS2
が非アクティブのために期限切れになります。無効化呼び出しは、ユーザーによってセッションが無効化された場合と同じようにインターセプトされ、セッションは無効化されたセッションにキューイングされます。この時点で、無効化されたセッションは、別のリクエストがシステムを通過して無効キューをチェックするまで、レプリケートされません。
ふぅ!(完了しました)
メンバーシップクラスタメンバーシップは、非常に単純なマルチキャストpingを使用して確立されます。各Tomcatインスタンスは定期的にマルチキャストpingを送信し、pingメッセージでインスタンスはレプリケーション用のIPとTCPリスンポートをブロードキャストします。インスタンスが指定された時間内にそのようなpingを受信しなかった場合、メンバーは死んでいると見なされます。非常にシンプルで、非常に効果的です!もちろん、システムでマルチキャストを有効にする必要があります。
TCPレプリケーションマルチキャストpingを受信すると、メンバーはクラスタに追加されます。次のレプリケーションリクエストで、送信インスタンスはホストとポート情報を使用してTCPソケットを確立します。このソケットを使用して、シリアル化されたデータを送信します。TCPソケットを選択した理由は、フロー制御と配信保証が組み込まれているためです。そのため、データを送信すると、確実に届きます。
分散ロックとフレームを使用したページ Tomcatは、クラスタ全体でセッションインスタンスを同期しません。このようなロジックの実装はオーバーヘッドが大きすぎ、様々な問題を引き起こします。クライアントが複数のリクエストを使用して同時に同じセッションにアクセスした場合、最後のリクエストがクラスタ内の他のセッションを上書きします。
JMXを使用したクラスタの監視
クラスタを使用する場合、モニタリングは非常に重要な問題です。クラスタオブジェクトの一部はJMX MBeanです。
起動スクリプトに以下のパラメータを追加してください。
set CATALINA_OPTS=\
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=%my.jmx.port% \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false
クラスタMBean一覧
名称 | 説明 | MBean ObjectName - エンジン | MBean ObjectName - ホスト |
---|---|---|---|
クラスタ | 完全なクラスタ要素 | type=Cluster |
type=Cluster,host=${HOST} |
DeltaManager | このマネージャはセッションを制御し、セッションレプリケーションを処理します。 | type=Manager,context=${APP.CONTEXT.PATH}, host=${HOST} |
type=Manager,context=${APP.CONTEXT.PATH}, host=${HOST} |
FarmWarDeployer | クラスタ内のすべてのノードへのアプリケーションのデプロイプロセスを管理します。 | サポートされていません。 | type=Cluster, host=${HOST}, component=deployer |
メンバー | クラスタ内のノードを表します。 | type=Cluster, component=member, name=${NODE_NAME} | type=Cluster, host=${HOST}, component=member, name=${NODE_NAME} |
ReplicationValve | このバルブは、バックアップノードへのレプリケーションを制御します。 | type=Valve,name=ReplicationValve |
type=Valve,name=ReplicationValve,host=${HOST} |
JvmRouteBinderValve | これは、セッションIDを現在のTomcat jvmrouteに変更するためのクラスタフォールバックバルブです。 | type=Valve,name=JvmRouteBinderValve, context=${APP.CONTEXT.PATH} |
type=Valve,name=JvmRouteBinderValve,host=${HOST}, context=${APP.CONTEXT.PATH} |
FAQ
詳細は、FAQのクラスタリングセクションを参照してください。