トップ 差分 一覧 ソース 検索 ヘルプ RSS ログイン

技術的雑談-複数のTomcat間でSessionの途切れないClusterを作る

技術的雑談-複数のTomcat間でSessionの途切れないClusterを作る


 環境

  • 使用OS:CentOS 3.5
  • httpd:Apache 2.0.46(多分2.0.xだったら大丈夫)
  • JDK 1.5.0_10
  • Apache tomcat 5.5.17
  • mod_jk(tomcat-connector) 1.2.20


 目的

  • Tomcat5.5の複数のインスタンス間でWeb ApplicationのObjectを共有し、フェイルセーフなClusterを作る。

今回の完成版の構成図は以下のようになります。

                 ┌――――┐
httpリクエスト→ │ Apache ├―――┐ 処理を依頼 ┌――――┐
                 |        |mod_jk|―――――→| Tomcat1|
httpレスポンス← |        |      |←―――――|        |
                 |        |      | 結果を返す └――――┘
                 |        |      |              ↑
                 |        |      |     SessionなどのObjectのミラーリング
                 |        |      |              ↓
                 |        |      | 処理を依頼 ┌――――┐
                 |        |      |―――――→| Tomcat2|
                 |        |      |←―――――|        |
                 |        |      | 結果を返す └――――┘
                 └――――┴―――┘    ※ 2つのTomcatは同一OSインスタンス上で稼動


 手順


Tomcatが使用するリソース


複数のTomcatを立ち上げてmod_jk経由でロードバランスさせるでのリソースに加え、以下のリソースを必要とします。

IPマルチキャスト用のIPアドレス1つ、Port1つ
Clusterへのメンバー追加、削除、状態変更通知、ハートビート(生存確認)などに使われているっぽいです。(すいません、ちゃんとは調べていませんが、多分server.xmlの同じエレメントに「mcastFrequency="500"」とか「mcastDropTime="3000"」とかあるので、そうかなぁ…と。)Defaultのserver.xml(コメントアウトされている)では「228.0.0.4」「45564」が使われています。
TCP Socket 4001番
実際のTomcat Objectの複製の為に使われるようです。

ここでの「マルチキャスト用IPアドレス・ポート」はClusterを組むTomcatのserver.xmlで全部同じにするのが正しいようです。
(IPアドレスにみんなで同じものを設定するなんて…理解しがたいですがこういうものらしいです。)

一方、Port 4001番の方は同一OSインスタンス上に複数のTomcatがいる場合、ずらしておかないとダメなようです。

(多分、マルチキャストで送っている情報の中に「私が変更を受け付けているのは4001番ポートだよ〜」みたいな情報が載っているんでしょうね。)

準備


Clusterの接続確認・生存確認にIPマルチキャストを使っているので、TomcatどうしがRouterの向こうにいる場合、そのRouterはIPマルチキャスト対応のRouterでなくてはならないようです。
多分、よくわからないうちや技術検証中はHub(RouterではなくSwitch)経由で接続する方が良いのではないかと思われます。

また、ここでは特に試していませんが、マルチキャスト用のNICと複製用のNICは別にできるっぽいです。

Install


Tomcatを2台以上と、それをちゃんと振り分けられるようにmod_jk、Apache httpdをセットアップしておいてください。
Apache httpd + mod_jk + Tomcat5.5の環境が構築できていればその他にソフトウェアを追加インストールする必要はありません。

設定


まずは、全Tomcatのserver.xmlを編集します。

Defaultのserver.xmlを使用している場合、後半部分はClusterの設定がコメントアウトされた状態で記載されています。

今回、私がCluster用に書き加えたのは以下のものです。

        <Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
                 managerClassName="org.apache.catalina.cluster.session.DeltaManager"
                 expireSessionsOnShutdown="false"
                 useDirtyFlag="true"
                 notifyListenersOnReplication="true">

            <Membership 
                className="org.apache.catalina.cluster.mcast.McastService"
                mcastAddr="228.0.0.4"
                mcastPort="45564"
                mcastFrequency="500"
                mcastDropTime="3000"/>

            <Receiver 
                className="org.apache.catalina.cluster.tcp.ReplicationListener"
                tcpListenAddress="auto"
                tcpListenPort="4001"
                tcpSelectorTimeout="100"
                tcpThreadCount="6"/>

            <Sender className="org.apache.catalina.cluster.tcp.ReplicationTransmitter" replicationMode="synchronous" waitForAck="true" />
            <Valve className="org.apache.catalina.cluster.tcp.ReplicationValve"
                   filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
            <Valve className="org.apache.catalina.cluster.session.JvmRouteBinderValve" enabled="true" />
            <ClusterListener className="org.apache.catalina.cluster.session.JvmRouteSessionIDBinderListener" />
            
            <Deployer className="org.apache.catalina.cluster.deploy.FarmWarDeployer"
                      tempDir="/tmp/war-temp/"
                      deployDir="/tmp/war-deploy/"
                      watchDir="/tmp/war-listen/"
                      watchEnabled="false"/>
                      
            <ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener"/>
        </Cluster>

これを「</Host>タグ」の直前に追記します。

また、Clusterに参加する全Tomcatのserver.xmlに同じように追記します。
ただし、同一OSインスタンス上に複数のTomcatが稼動している場合のみ、<Receiver>内の「tcpListenPort」の値を、ずらしてください。<Membership>の「mcastAddr」や「mcastPort」は変える必要が ありません。 むしろ変えちゃいけないっぽい。

<Cluster useDirtyFlag="true" >
Web Application内でTapestryを使っている場合はこれをfalseに変えないと不具合がおこるらしいです。(未確認)
<Membership>
同じClusterグループに属しているサーバを見つけ出す為に使われるっぽいですね。(未確認)NICが複数刺さっているサーバの場合、228.0.0.4宛てのパケットが送られるNICをroute addコマンドで教えてあげないとならないかもしれません。(OSのDefault routerがWAN側に向いていたりすると、セキュリティー的な問題でマルチキャストパケットを内内接続の別のLANに向けた方がいいと思います。パフォーマンスが求められる場合などもサービスのNICとCluster用のNICは分けたほうが良いと思います。)
<Sender replicationMode="synchronous" waitForAck="true" />
Objectの複製について「syncronous」「asyncronouse」「pool」が選べるようです。またwaitForAckは完了まで待つか待たないかを設定できるようです。(未確認)
<Valve className="〜ReplicationValve" filter=".*\.gif;.*\.js;〜"/>
Clusterノード間で複製しないものを指定できるようです。普通はこのままで良いでしょう。
<Valve className="org.apache.catalina.cluster.session.JvmRouteBinderValve" enabled="true" />
…よくわかりません。とりあえず書いておきました。
<ClusterListener className="org.apache.catalina.cluster.session.JvmRouteSessionIDBinderListener" />
…よくわかりません。多分Cluster内でSession Objectを複製する為のものでしょう。
<Deployer>
別のClusterノードから転送されてきたObjectやファイルを格納しておくキャッシュの設定だと思われます。OS側の都合で/tmpなどが使用不可の場合は別の場所にしましょう。
<ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener"/>
…よくわかりません。とりあえず書いておきました。

未調査の項目が多くてすいません…。もしかしたら余計な事もやってるかもしれません。
(一応この後の検証方法で問題が出なかったので…。)

次に、ClusterしたいWeb Applicationのweb.xmlに<distributable/>というマークを追加します。
web.xmlはWeb ApplicationのDirectory直下の「WEB-INF」Directory内にあります。

追記する位置は「<display-name>の後、<filter>の前」です。
(場所が間違っているとweb.xmlがDTD違反だと言われ、Web Applicationが立ち上がりません。)

起動・終了


前記の設定を終えたら両Tomcat、httpdを再起動する。
エラーが出なければひとまずOK。

確認


  • まず、立ち上がったTomcatの$TOMCAT_HOME/log/catalina.outをチェックし、以下の文言があることを確認する。

Creating ClusterManager for context XXXX using class org.apache.catalina.cluster.session.DeltaManager

※簡単には「DeltaManager」でgrepして、引っかかればOK?

  • 先程のSession ID表示jspを実行する。何度かreloadしてSession IDが固定されている事を確認する。

また、jkstatusでも特定のworkerに処理が固定化されていることを確認。

  • jkstatusで上記のworkerをDisableにする。

worker nameの右の「E|R」のEをクリックし、次の画面でDisableを選択する。

  • もう一度jspページをreloadする。

Session IDのjvmRoute部分以外が変わらなければ成功。

ちなみにこの状態で先程のworkerをActiveに戻してもSessionは自然とは元のworkerにはFail backしない。
(担当しているworkerを直接落とせば別ですが。)



 関連項目







 履歴

2007/01/18 -- 初版

技術的雑談へ戻る

 突っ込み


name   comment  
URL (入力するとす ぱ むとみなします!)


技術的雑談へ戻る

TrackBack

TrackBack URL for this entry:
http://www.himajin2001.com/fswiki/tb.cgi/%B5%BB%BD%D1%C5%AA%BB%A8%C3%CC%2D%CA%A3%BF%F4%A4%CETomcat%B4%D6%A4%C7Session%A4%CE%C5%D3%C0%DA%A4%EC%A4%CA%A4%A4Cluster%A4%F2%BA%EE%A4%EB

技術的雑談へ戻る

最終更新日時:最終更新時間:2012年01月20日 17時52分36秒
トップページに戻る