The Apache Tomcat Servlet/JSP Container

The Apache Tomcat 5.5 Servlet/JSP Container

Apache Logo

Links

User Guide

Reference

Apache Tomcat Development

The Apache Tomcat 5.5 Servlet/JSP Container

Clustering/Session Replication HOW-TO

Printer Friendly Version
print-friendly
version
クイック・スタート

Tomcat 5.5 コンテナでセッション・レプリケーションを走らせるには,次のステップを完遂します:

  • セッション・アトリビュートはすべてjava.io.Serializableを実装する必要があります。
  • server.xml の Cluster エレメントのコメントアウトを解除します。
  • server.xml の Valve(ReplicationValve) エレメントのコメントアウトを解除します。
  • 同一マシンで複数の Tomcat インスタンスを走らせるときは, tcpListenPort アトリビュートが各インスタンスで一意的になるようにします。
  • web.xml<distributable/> を設けるか, <Context distributable="true" /> でセットします。 [訳注: web.xml については Sun の Servlet 2.3 仕様書を参照。Context エレメントについては context.html を参照。ただし,後者に distributable の記述はない]
  • Engine に jvmRoute アトリビュートをセットします。 <Engine name="Catalina" jvmRoute="node01" > [訳注: Engine エレメントについては engine.html を参照]
  • すべてのノードが同じ時刻を持ち,NTP サービスで同期されていること!
  • ロードバランサが sticky session mode に設定されていることを確認します。

ロード・バランシングは Load Balancing の章に見るように多くの技術で達成できます。

注意: セッション・ステートはクッキーによってトラックされます。 ですから,外から見たとき URL が同じに見えなくてはなりません。 そうしないと新しいセッションが作られることになります。

クラスタリング・サポートは現在,JDK バージョン 1.4 以降を必要とします。

概観

Tomcat でセッション・レプリケーションを可能にするには,三つの方法があります。どれも正確に同じものを達成します:

  1. セッション・パーシステンスを使い,セッションを共有ファイル・システムにセーブします (PersistenceManager + FileStore)
  2. セッション・パーシステンスを使い,セッションを共有データベースにセーブします (PersistenceManager + JDBCStore)
  3. メモリ内レプリケーションを使い,Tomcat 5 に同梱の SimpleTcpCluster を使います (server/lib/catalina-cluster.jar)

このリリースのセッション・レプリケーションでは,Tomcat はセッション・ステートの all-to-all のレプリケーションを行います。 これは,クラスタが小さいときだけ効率的なアルゴリズムです。 大規模クラスタについては,次のリリースで プライマリー=セカンダリー・セッション・レプリケーション をサポートする予定です。これはセッションを1台またはたかだか2台のバックアップ・サーバに格納します [訳注: 最近安定版がリリースされた Tomcat 6 はクラスタリングの改良を主要な変更点に 挙げており,BackupManager により同方式を実装しています]。 現在のところ,domain worker アトリビュート (mod_jk > 1.2.8) を使ってクラスタ・パーティションを構築すれば, とてもスケーラブルなクラスタ・ソリューションの可能性があります。 all-to-all の環境でネットワークのトラフィックを低く保つために,クラスタを小さなグループに分割できます。 これは,グループごとに別々のマルチキャスト・アドレスを使うことで容易に達成できます。 とても単純なセットアップではこのようになるでしょう:

        DNS Round Robin
               |
         Load Balancer
          /           \
      Cluster1      Cluster2
      /     \        /     \
  Tomcat1 Tomcat2  Tomcat3 Tomcat4

ここで言及すべき重要なことは,セッション・レプリケーションはクラスタリングの初歩にすぎないということです。 クラスタを実装するために使われる他のポピュラーな概念はファーミング (farming) です。 あなたがアプリを1個のサーバに配置する,するとクラスタがその配置をクラスタ全体に配布する,というものです。 これはすべて FarmWarDeployer で行える能力です (server.xml の Cluster の例を参照)。

動作方法

どのようにクラスタが動作するのか理解しやすくするために,私たちはあなたを一連のシナリオに案内します。 このシナリオでは私たちは二つの tomcat インスタンス TomcatATomcatB だけを使うことにします。下記のシーケンスのイベントをカバーします。

  1. TomcatA が起動する
  2. TomcatB が起動する (TomcatA が起動し終わるのを待つ)
  3. TomcatA がリクエストを受け取る。セッション S1 が作られる
  4. TomcatA がクラッシュする
  5. TomcatB がセッション S1 のリクエストを受け取る
  6. TomcatA が起動する
  7. TomcatA がリクエストを受け取る。セッション (S1) の無効化が求められる (invalidate is called on the session (S1))
  8. TomcatB が新しいセッション (S2) のリクエストを受け取る
  9. TomcatA セッション S2 が放置により (due to inactivity) 無効化される

Ok, さてこのシーケンスで,正確には何がセッション・レプリケーション・コードに起こっているのか,あなたを案内しましょう。

  1. TomcatA が起動する

    Tomcat が標準的な起動シーケンスでスタートします。 Host オブジェクトが生成されたとき,cluster オブジェクトがそれに関連づけられます。 各 context をパースするとき,もしも distributable エレメントが web.xml の代わりにあれば, Tomcat は Cluster クラス (この場合 SimpleTcpCluster) に対し, レプリケートされた context のマネージャを生成するように頼みます。 web.xml に distributable をセットしてクラスタリングをイネーブルにしたときも同様です [訳注: 原文は英語文法として破格。ここではピリオド等を補って訳した]。 Tomcat は StandardManager のかわりにその context に対し DeltaManager を生成します。 cluster クラスは membership サービス (マルチキャスト) とレプリケーション・サービス (tcp ユニキャスト) を起動します。 アーキテクチャの詳細についてはこのドキュメントのずっと後で [説明します]。

  2. TomcatB が起動する

    TomcatB が起動するときは,ひとつの例外を除いて TomcatA と同じシーケンスをたどります。 クラスタがスタートし, membership (TomcatA, TomcatB) が確立されます。 それから TomcatB はクラスタの既存サーバ (この場合 TomcatA) に対し,そのセッション・ステートをリクエストします。 TomcatA はリクエストに応答し,TomcatB が HTTP リクエストでの待ち受けを始める前に,ステートが TomcatA から TomcatB へ転送されます。 TomcatA が応答しない場合, TomcatB は 60 秒後にタイム・アウトし,log エントリを発行します。 web.xml に distributable を持っている各 web アプリケーションに対し,それぞれセッション・ステートが転送されます。 注: セッション・レプリケーションを効率的に使うには,あなたの tomcat インスタンスをすべて同じようにコンフィグすべきです。

  3. TomcatA がリクエストを受け取る。セッション S1 が作られる

    TomcatA に到来するリクエストは,セッション・レプリケーション無しのときと正確に同様に扱われます。 アクションはリクエストの完了時に起こります。 レスポンスがユーザへ返される前に ReplicationValve がリクエスト [訳注: レスポンスの誤り?] を横取ります[訳注: この2文の原文は comma fault で文意不明瞭]。 この時点でそれはセッションが変更されていることを発見し,TCP を使ってセッションを TomcatB に replacata [ママ] します。 直列化されたデータをオペレーティング・システムの TCP ロジックに渡してしまった後,valve パイプラインを通じてリクエスト [レスポンス?] がユーザに戻されます。 リクエストごとにセッション全体がレプリケートされますから,レプリケートされるべきセッションのアトリビュートを setAttribute や removeAttribute を呼ばずに変更できます。 セッションがレプリケートされる回数を最適化するために, コンフィグレーション・パラメタ useDirtyFlag を使うことができます。

  4. TomcatA がクラッシュする

    TomcatA がクラッシュする時,TomcatB は TomcatA がクラスタから脱落したという知らせを受け取ります。 TomcatB は TomcatA を membership リストから外します。 TomcatA はこれ以降 TomcatB に起きたいかなる変化も知らされなくなります。 ロード・バランサは TomcatA から TomcatB へリクエストをリダイレクトするはずです。 セッションはすべて継続します。

  5. TomcatB がセッション S1 のリクエストを受け取る

    エキサイティングなことは何もありません。 TomcatB はリクエストを他のどんなリクエストとも同じように処理します。

  6. TomcatA が起動する

    起動する時, TomcatA は,新しいリクエストを受け取って自分自身を利用可能にする前に 上記 1) 2) に記述された起動シーケンスをたどります。 クラスタに加入し,すべてのセッションの現在のステートについて TomcatB にコンタクトします。 セッション・ステートを受け取ったら,ローディングを終了して HTTP/mod_jk ポートを開きます。 ですから TomcatB からセッション・ステートを受け取ってしまうまでは TomcatA でリクエストは処理されません。

  7. TomcatA がリクエストを受け取り, セッション (S1) の無効化が求められる (invalidate is called on the session (S1))

    呼出しが [TomcatB に] 横取りされたことは,無効化の理由になります [訳注: 原文は "The invalidate is call is intercepted" --動詞 invalidate をドイツ語のように自由に名詞として使っているのだろうか?]。 セッションが,[他の] 無効化されたセッションと一緒にキューに入れられます。 リクエストの完了時,変更されたセッションを送出するかわりに "期限切れ" メッセージを TomcatB へ送出し,TomcatB も同様にセッションを無効化します。

  8. TomcatB が新しいセッション (S2) のためのリクエストを受け取る

    ステップ 3) と同じシナリオです。

  9. TomcatA セッション S2 が放置 [訳注: 原文では "inactivity" (不活発さ)。 ユーザが Web ページを表示したまま放置したという意味か?] により無効化される

    セッションは,ユーザにより無効化されたときも,呼出しが横取りされた場合と同じように無効化されます [訳注: 原文は意味不明瞭。訳文は推測による仮訳。 "The invalidate is call is intercepted the same was as when a session is invalidated by the user"]。 セッションは,[他の] 無効化されたセッションと一緒にキューに入れられます。 この時点では invalidet [ママ] セッションは,他のリクエストがシステムから 到来して無効化キューをチェクするまでレプリケートされません [訳注: 無効化されたセッションがレプリケートされるはずはなく意味不明瞭だが, 単に放置されているだけでは "期限切れ" メッセージは送出されず, ほかにリクエストがあったときについでに処分される,という意味か?]。

ふーっ! (Phuuuhh!) :)

Membership クラスタリングの membership は非常に簡単なマルチキャスト ping を使って確立されます。 各 Tomcat インスタンスは定期的にマルチキャスト ping を送出します。 ping メッセージでインスタンスはその IP とレプリケーション用 TCP listen ポートをブロードキャストします。 所定の時間枠内にインスタンスがこのような ping を受け取らなかったならば, そのメンバは死んだと見なされます。 とても単純ですが,とても効果的です! もちろん,あなたはシステムのマルチキャスティングを有効にしておく必要があります。 [訳注: 実際には,いわゆる ping コマンドと異なり,ICMP ではなく,java.net.MulticastSocket による UDP を通信に利用している]

TCP レプリケーション いったんマルチキャスト ping が受け取られると,メンバがクラスタに追加されます。 次回のレプリケーション・リクエストでは,送出側のインスタンスはそのホストとポート番号の情報を使って TCP ソケットを確立します。 このソケットを使って直列化データを送出します。 私が TCP ソケットを選んだ理由は,それがフロー制御と到達保証性を組込んでいるからです。 だから,私が何かデータを送った時,それは送り先に届くと分かるわけです :)

分散ロッキングとフレームを使ったページ Tomcat はクラスタ間で同期的にセッション・インスタンスを保持するわけではありません。 そのようなロジックは多くのオーバーヘッドを生み,あらゆる種類の問題を引き起こすでしょう。 もしもクライアントが複数のリクエストを使って同じセッションに同時にアクセスしたならば, 最後のリクエストがクラスタ内の他のセッション [のレプリカ] を上書きすることになります。

Cluster Architecture

Component Levels:

         Server
           |
         Service
           |
         Engine
           |  \ 
           |  --- Cluster --*
           |
         Host
           |
         ------
        /      \
     Cluster    Context(1-N)                 
        |             \
        |             -- Manager
        |                   \
        |                   -- DeltaManager
        |
     -----------------------------
     |          |         |       \
   Receiver    Sender   Membership  \
     \                               -- Valve
     -- SocketReplicationListener    |      \
     -- ReplicationListener          |       -- ReplicationValve
                                     |       -- JvmRouteBinderValve 
                                     |
                                     -- LifecycleListener 
                                     |
                                     -- ClusterListener 
                                     |      \
                                     |       -- ClusterSessionListener
                                     |       -- JvmRouteSessionIDBinderListener
                                     |
                                     -- Deployer 
                                            \
                                             -- FarmWarDeployer
      
      
   Sender
    \
    -- ReplicationTransmitter 
             |
             ---------
                      \
                   IDataSender
                          \
                          |
                          --- (sync)
                          |  \
                          |   -- PooledSocketSender   (pooled)
                          |   -- SockerSender         (synchronous)
                          |                                
                          --- (async)
                             \
                              -- AsyncSocketSender     (asynchronous)
                              -- FastAsyncSocketSender (fastasyncqueue)         

Cluster コンフィグレーション

cluster コンフィグレーションはサンプルの server.xml ファイルで説明されています。 注意すべき点として, mcastXXX で始まるアトリビュートは membership multicast ping 用で, tcpXXX で始まるアトリビュートは実際の TCP レプリケーション用だということです。

membership は全 tomcat インスタンスにより確立されます。 全 tomcat インスタンスは同じ multicast IP アドレスとポート番号でブロードキャスト・メッセージ を送ります [訳注: 原文は英語として破格。 "The membership is established by all the tomcat instances are sending broadcast messages on the same multicast IP and port" --おそらく are を省くか,are の前に which を補うべき]。 TCP listen port は,セッション・レプリケーションを他のメンバから受け取るポートである。

replication valve は,リクエストが完了した時を見つけて,レプリケーションを始めるために使われます。

性能について最も重要な考慮事項のひとつは,レプリケーションの (プール化または非プール化) 同期モード 対 非同期モードです。 同期レプリケーション・モードでは,レプリケートされたセッションが LAN ケーブルを越えて伝送され他の全クラスタ・ノードで再実体化されるまで,リクエストは返されません。 同期レプリケーションには二つの設定があります。プール化 (pooled) と非プール化です。 非プール化設定 (つまり replicationMode="fastasnycqueue" または "synchronous") ではすべてのレプリケーション・リクエストが単一のソケットで伝送されます。 同期モードの使用は,多量のメッセージが生成されるときボトルネックになりかねません。 replicationMode="pooled" にセットすることで,このボトルネックを克服できますが, 今度は worker スレッドがレプリケーションでブロックされます。 ここでの推奨方法は,到来するレプリケーション・リクエストを処理するスレッドの数を増やすことです。 これが server.xml の cluster セクションの tcpThreadCount プロパティです。 プール化設定は,複数のソケットを使って性能を向上させることを意味します。 非同期レプリケーションは,sticky session を fail over するまで維持するときに使うとよいでしょう。 このときは,データのレプリケーションにかかる時間ではなく,リクエストにかかる時間が重要になります。 このとき tcpThreadCount を ノード数 - 1 にします。 非同期レプリケーションをしているときは,データがレプリケートされる前にリクエストが返されます。 非同期レプリケーションはより短いリクエスト時間をもたらします。 その一方,同期レプリケーションは,リクエストが返される前にセッションがレプリケートされることを保証します。

パラメタ "replicationMode" には4とおりの設定があるわけです: "pooled", "synchronous", "asynchronous" そして "fastasyncqueue"

シンブルなクラスタ・コンフィグレーション

シンプルな1行コンフィグレーション [訳注: Cluster タグに注目]

   <Server                 port="8011" 
                       shutdown="SHUTDOWN" >
    <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="9012" 
                      protocol="AJP/1.3"
        <Connector         port="9013"
                     maxThreads="100"
                minSpareThreads="4"
                maxSpareThreads="4"
        />
        <Engine            name="Catalina" 
                   defaultHost="localhost" 
                        jvmRoute="node1">
        <Realm        className="org.apache.catalina.realm.UserDatabaseRealm"
                   resourceName="UserDatabase" />
            <Host          name="localhost"
                        appBase="webapps">
             <Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"/>
            </Host>
        </Engine>
    </Service>
</Server>

デフォルト・モードのコンフィグレーションは, fastasyncqueue モードのクラスタ・コンフィグレーションを, 下記のパラメタでセットアップします:
  • 228.0.0.4 で Membership レシーバを開き,マルチキャスト udp ポート 8012 に送信します。
  • 1 秒ごとに membership を送り,30 秒後にメンバを脱落させます。
  • デフォルト ip インタフェースの 8015 から 8019 までの最初の空きポートで message レシーバを開きます。
  • SocketReplicationListener で message を受け取ります。
  • ReplicationTransmitterfastasyncqueue sender モードに設定します。
  • ClusterSessionListenerReplicationValve を追加します。

注意: あなたが開発マシンで手早くテスト用クラスタを作りたいとき,このコンフィグレーションを使いなさい。 cluster の下位エレメントでデフォルトの属性を変更できます。 sender., receiver., service., manager., valve. および listener の cluster 属性プレフィックスを使います。
は cluster をネットワーク接続された Windows ラップトップで設定し,ポートの範囲を変更しています。

<Cluster                 className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
          service.mcastBindAddress="127.0.0.1" 
            receiver.tcpListenPort="9070" 
         receiver.tcpListenMaxPort="9075" />

警告: あなたがあなた [の] 下位エレメントを追加したとき, [それらは] デフォルトを完全に上書きします。
は cluster を cluster failover jsessionid サポートで設定しています。 この場合あなたはデフォルトモード Cluster リスナ ClusterSessionListenerReplicationValve も必要です。
<Cluster                 className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
          service.mcastBindAddress="127.0.0.1" 
            receiver.tcpListenPort="9070" 
         receiver.tcpListenMaxPort="9075" >
       <ClusterListener  className="org.apache.catalina.cluster.session.ClusterSessionListener" />
       <ClusterListener  className="org.apache.catalina.cluster.session.JvmRouteSessionIDBinderListener" />
       <Valve            className="org.apache.catalina.cluster.tcp.ReplicationValve"
                            filter=".*\.gif;.*\.js;.*\.css;.*\.png;.*\.jpeg;.*\.jpg;.*\.htm;.*\.html;.*\.txt;"
                  primaryIndicator="true" />
	   <Valve            className="org.apache.catalina.cluster.session.JvmRouteBinderValve"
	                      enabled="true"  />
<Cluster/>

すべてのホストのためのシンプルなエンジン・クラスタ・コンフィグレーション

シンブルな1行エンジン・コンフィグレーション

   <Server                 port="8011" 
                       shutdown="SHUTDOWN" >
    <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="9012" 
                      protocol="AJP/1.3"
        <Connector         port="9013"
                     maxThreads="100"
                minSpareThreads="4"
                maxSpareThreads="4"
        />
        <Engine            name="Catalina" 
                   defaultHost="localhost" 
                        jvmRoute="node01">
        <Realm        className="org.apache.catalina.realm.UserDatabaseRealm"
                   resourceName="UserDatabase" />
        <Cluster      className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"/>
            <Host          name="localhost"
                        appBase="webapps"/>
        </Engine>
    </Service>
</Server>

シンブルなホスト・クラスタ例として上記のデフォルト・モード・コンフィグレーションの説明を見なさい。 [原文: "See default mode configuration description as simple host cluster example before."]

複雑なクラスタ・コンフィグレーション


完全な下位エレメントをもってクラスタを設定します。 master farm deployer としてこのノードをアクティベートします。 メッセージ・レシーバは,6本の並列 worker スレッドをもった NIO ベースの ReplicationListener です。

       <Server                 port="8011" 
                       shutdown="SHUTDOWN" >
    <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="9012" 
                      protocol="AJP/1.3"
        <Connector         port="9013"
                     maxThreads="100"
                minSpareThreads="4"
                maxSpareThreads="4"
        />
        <Engine            name="Catalina" 
                   defaultHost="localhost" 
                        jvmRoute="node01">
        <Realm        className="org.apache.catalina.realm.UserDatabaseRealm"
                   resourceName="UserDatabase" />
            <Host          name="localhost"
                        appBase="webapps">
                <Cluster                  className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
                                       doClusterLog="true"
                                     clusterLogName="clusterlog"
                                  manager.className="org.apache.catalina.cluster.session.DeltaManager"
                   manager.expireSessionsOnShutdown="false"
               manager.notifyListenersOnReplication="false"
        manager.notifySessionListenersOnReplication="false"
                            manager.sendAllSessions="false"
                        manager.sendAllSessionsSize="500"
                    manager.sendAllSessionsWaitTime="20">
                  <Membership 
                                          className="org.apache.catalina.cluster.mcast.McastService"
                                          mcastAddr="228.0.0.4"
                                   mcastBindAddress="127.0.0.1" 
                                 mcastClusterDomain="d10" 
                                          mcastPort="45564"
                                     mcastFrequency="1000"
                                      mcastDropTime="30000"/>
                  <Receiver 
                                           className="org.apache.catalina.cluster.tcp.ReplicationListener"
                                    tcpListenAddress="auto"
                                       tcpListenPort="9015"
                                  tcpSelectorTimeout="100"
                                      tcpThreadCount="6"
                  <Sender
                                           className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
                                     replicationMode="fastasyncqueue"
                        doTransmitterProcessingStats="true"
                                   doProcessingStats="true"
                                      doWaitAckStats="true"
                                       queueTimeWait="true"
                                        queueDoStats="true"
                                      queueCheckLock="true"
                                          ackTimeout="15000"
                                          waitForAck="true"
                                    keepAliveTimeout="80000"
                            keepAliveMaxRequestCount="-1"/>
                  <Valve                   className="org.apache.catalina.cluster.tcp.ReplicationValve"
                                              filter=".*\.gif;.*\.js;.*\.css;.*\.png;.*\.jpeg;.*\.jpg;.*\.htm;.*\.html;.*\.txt;"
                                    primaryIndicator="true" />
                  <Valve                    className="org.apache.catalina.cluster.session.JvmRouteBinderValve"
                                             enabled="true" />	
                  <ClusterListener         className="org.apache.catalina.cluster.session.ClusterSessionListener" />
                  <ClusterListener         className="org.apache.catalina.cluster.session.JvmRouteSessionIDBinderListener" />
                  <Deployer                className="org.apache.catalina.cluster.deploy.FarmWarDeployer"
                                            tempDir="${catalina.base}/war-temp"
                                          deployDir="${catalina.base}/war-deploy/"
                                           watchDir="${catalina.base}/war-listen/"
                                       watchEnabled="true"/>
                  </Cluster>
            </Host>
        </Engine>
    </Service>
</Server>

Cluster Configuration for ReplicationTransmitter

List of Attributes
Attribute Description Default value
replicationMode replication mode (synchronous, pooled, asynchronous or fastasyncqueue) pooled
processSenderFrequency Control the sender keepalive status and drop sender socket connection after timeout is reached. Check every processSenderFrequency value engine background ticks. 2
compress compress bytes before sending (consume memory, but reduce network traffic - GZIP) false
ackTimeout acknowledge timeout and only usefull it waitForAck is true 15000
waitForAck Wait for ack after data send false
autoConnect is sender disabled, fork a new socket false
doTransmitterProcessingStats create processing time stats false

Example to get statistic information, wait for ack at every message send and transfer at compressed mode

    <Sender
      className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
      replicationMode="fastasyncqueue"
      compress="true"
      doTransmitterProcessingStats="true"
      ackTimeout="15000"
      waitForAck="true"
      autoConnect="false"/>

Cluster Configuration for ReplicationTransmitter (fastayncqueue - mode)

List of Attributes
Attribute Description Default value
keepAliveTimeout active socket keep alive timeout 60000
keepAliveMaxRequestCount max request over this socket -1
doProcessingStats create Processing time stats false
doWaitAckStats create waitAck time stats false
resend resend message after failure, can overwrite at message false
queueDoStats activated queue stats false
queueCheckLock check to lost locks false
queueAddWaitTimeout queue add wait time (tomcat connector thread waits) 10000
queueRemoveWaitTimeout queue remove wait time (queue thread waits) 30000
maxQueueLength max queue length (default without limit) -1
threadPriority change queue thread priority (1-10 ; 5 is normal) 5

Example to get a lot of statistic information and no wait for ACK

    <Sender
      className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
      replicationMode="fastasyncqueue"
      doTransmitterProcessingStats="true"
      doProcessingStats="true"
      queueTimeWait="true"
      queueDoStats="true"
      queueCheckLock="true"
      waitForAck="false"
      autoConnect="false"
      keepAliveTimeout="320000"
      keepAliveMaxRequestCount="-1"/>

Cluster Configuration for ReplicationTransmitter ( asynchronous - mode)

List of Attributes
Attribute Description Default value
keepAliveTimeout active socket keep alive timeout 60000
keepAliveMaxRequestCount max request over this socket -1
doProcessingStats create Processing time stats false
doWaitAckStats create waitAck time stats false
resend resend message after failure, can overwrite at message false

Example to get a processing statistic information, resend after failure and wait for ACK

    <Sender
      className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
      replicationMode="asynchronous"
      doProcessingStats="true"
      doWaitAckStats="true"
      waitForAck="true"
      ackTimeout="30000"
      resend="true"
      keepAliveTimeout="320000"
      keepAliveMaxRequestCount="-1"/>

Cluster Configuration for ReplicationTransmitter ( synchronous - mode)

List of Attributes
Attribute Description Default value
keepAliveTimeout active socket keep alive timeout 60000
keepAliveMaxRequestCount max request over this socket -1
doProcessingStats create Processing time stats false
doWaitAckStats create waitAck time stats true
resend resend message after failure, can overwrite at message false

Example to get a no processing statistic information, no wait for ACK, after 10000 request renew socket and autoconnect before first request is send.

    <Sender
      className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
      replicationMode="synchronous"
      autoConnect="true"
      keepAliveTimeout="-1"
      keepAliveMaxRequestCount="100000"/>

Cluster Configuration for ReplicationTransmitter ( pooled - mode)

List of Attributes
Attribute Description Default value
keepAliveTimeout active socket keep alive timeout 60000
keepAliveMaxRequestCount max request over this socket -1
maxPoolSocketLimit max pooled sockets (Sender Sockets) 25
resend resend message after failure, can overwrite at message false

Example to get a no processing statistic information, wait for ACK, after 10000 request renew socket, only 10 SockerSender available and autoconnect before first request is send.

    <Sender
      className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
      replicationMode="pooled"
      autoConnect="true"
      maxPoolSocketLimit="10"
      keepAliveTimeout="-1"
      keepAliveMaxRequestCount="10000"
      waitForAck="true" />

Cluster Configuration for ReplicationTransmitter ( DeltaManager Attribute)

List of Attributes
Attribute Description Default value
expireSessionsOnShutdown When server stopped, expire all sessions also at backup nodes (only for testing) false
maxActiveSessions Number of active sessions. (Default is no limit) -1
notifyListenersOnReplication Notify application session listener to session creation and expiring events at backup nodes true
notifySessionListenersOnReplication Notify application session listener to attribute changes at backup nodes true
stateTransferTimeout Timeout that session state transfer is complete. Is attribute stateTransferTimeout == -1 then application wait that other node send the complete session state 60
sendAllSessions Flag to send sessions as splited blocks true
sendAllSessionsSize Number of serialize sessions inside a send block session message. Only useful when sendAllSessions==false 1000
sendAllSessionsWaitTime wait time between two session send blocks. 2000
sendClusterDomainOnly Send all session messages only to member inside same cluster domain (value od Membership attribute mcastClusterDomain). Also don't handle session messages from other domains. true
stateTimestampDrop DeltaManager queued Sessions messages when send GET_ALL_SESSION to other node. with stateTimestampDrop all messages before state transfer message creation date (find session) are dropped. Only other GET_ALL_SESSION events are handle with date before state transfer message. true

Example send all sessions at separate blocks. Serialize and send 100 session inside one block. Wait maximale two minutes before the complete backup sessions are loaded inside tomcat boot process. Between send blocks wait 5 secs to transfers the session block to other node. This save memory when you use the async modes with queues.

    <Cluster className="org.apache.catalina.tcp.SimpleTcpCluster"
      managerClassName="org.apache.catalina.cluster.session.DeltaManager"
      manager.stateTransferTimeout="120"
      manager.sendAllSessions="false"
      manager.sendAllSessionsSize="100"
      manager.sendAllSessionsWaitTime="5000"
      "/>

Note:
As Cluster.defaultMode=true you can configure the manager attributes with prefix manager..
Note:
With Cluster.setProperty(<String>,<String>) you can modify attributes for all register managers. The method exists as MBeans operation.

Bind session after crash to failover node

As you configure more then two nodes at same cluster for backup, most loadbalancer send don't all your requests after failover to the same node.

The JvmRouteBinderValve handle tomcat jvmRoute takeover using mod_jk module after node failure. After a node crashed the next request going to other cluster node. The JvmRouteBinderValve now detect the takeover and rewrite the jsessionid information to the backup cluster node. After the next response all client request goes direct to the backup node. The change sessionid send also to all other cluster nodes. Well, now the session stickyness work directly to the backup node, but traffic don't go back too restarted cluster nodes!
As jsessionid was created by cookie, the change JSESSIONID cookie resend with next response.

You must add JvmRouteBinderValve and the corresponding cluster message listener JvmRouteSessionIDBinderListener. As you add the new listener you must also add the default ClusterSessionListener that receiver the normal cluster messages.

<Cluster className="org.apache.catalina.tcp.SimpleTcpCluster" >
...
     <Valve className="org.apache.catalina.cluster.session.JvmRouteBinderValve"
               enabled="true" sessionIdAttribute="takeoverSessionid"/>	
     <ClusterListener className="org.apache.catalina.cluster.session.JvmRouteSessionIDBinderListener" />
     <ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener" />
...
<Cluster>

Hint:
With attribute sessionIdAttribute you can change the request attribute name that included the old session id. Default attribuite name is org.apache.catalina.cluster.session.JvmRouteOrignalSessionID.

Trick:
You can enable this mod_jk turnover mode via JMX before you drop a node to all backup nodes! Set enable true on all JvmRouteBinderValve backups, disable worker at mod_jk and then drop node and restart it! Then enable mod_jk Worker and disable JvmRouteBinderValves again. This use case means that only requested session are migrated.

JMX によるクラスタのモニタリング

モニタリングは,あなたがクラスタを使う時の非常に重要な問題です。 クラスタ・オブジェクトのいくつかは JMX MBean です。

Java 5 [ならば] 起動スクリプトに下記のパラメタを追加します。

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

JDK 1.4 で JMX をアクティベートする [には]:

  1. compat パッケージをインストールします。
  2. mx4j-tools.jar を common/lib にインストールします (tomcat のリリースと同じバージョンの mx4j を使います)。
  3. MX4J JMX HTTP Adaptor をあなたの AJP Connector に設定します

    <Connector port="${AJP.PORT}" 
       handler.list="mx"
       mx.enabled="true" 
       mx.httpHost="${JMX.HOST}" 
       mx.httpPort="${JMX.PORT}" 
       protocol="AJP/1.3" />
    
  4. tomcat をスタートさせ,ブラウザで http://${JMX.HOST}:${JMX.PORT} を見ます。
  5. connector パラメタ mx.authMode="basic" mx.authUser="tomcat" mx.authPassword="strange" でアクセスを制御できます!

List of Cluster Mbeans
Name Description MBean ObjectName - Engine MBean ObjectName - Host
Cluster The complete cluster element type=Cluster type=Cluster,host=${HOST}
ClusterSender Configuration and stats of the sender infrastructure type=ClusterSender type=ClusterSender,host=${HOST}
ClusterReceiver Configuration and stats of the recevier infrastructure type=ClusterReceiver type=ClusterReceiver,host=${HOST}
ClusterMembership Configuration and stats of the membership infrastructure type=ClusterMembership type=ClusterMembership,host=${HOST}
IDataSender For every cluster member it exist a sender mbeans. It exists speziall MBeans to all replication modes type=IDataSender, senderAddress=${MEMBER.SENDER.IP}, senderPort=${MEMBER.SENDER.PORT} type=IDataSender,host=${HOST}, senderAddress=${MEMBER.SENDER.IP}, senderPort=${MEMBER.SENDER.PORT}
DeltaManager This manager control the sessions and handle session replication type=Manager,path=${APP.CONTEXT.PATH}, host=${HOST} type=Manager,path=${APP.CONTEXT.PATH}, host=${HOST}
ReplicationValve This valve control the replication to the backup nodes type=Valve,name=ReplicationValve type=Valve,name=ReplicationValve,host=${HOST}
JvmRouteBinderValve This is a cluster fallback valve to change the Session ID to the current tomcat jvmroute. type=Valve,name=JvmRouteBinderValve, path=${APP.CONTEXT.PATH} type=Valve,name=JvmRouteBinderValve,host=${HOST}, path=${APP.CONTEXT.PATH}

FAQ

Please see the clustering section of the FAQ.


Copyright © 1999-2006, Apache Software Foundation