トップ 一覧 検索 ヘルプ 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

*[[複数のTomcatを立ち上げてmod_jk経由でロードバランスさせる|技術的雑談-複数のTomcatを立ち上げてmod_jk経由でロードバランスさせる]]が完了していること。

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

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

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


!!手順

!Tomcatが使用するリソース

[[複数のTomcatを立ち上げてmod_jk経由でロードバランスさせる|技術的雑談-複数の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?

*[[先程|技術的雑談-複数のTomcatを立ち上げてmod_jk経由でロードバランスさせる]]の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を直接落とせば別ですが。)



!!関連項目

*[[LinuxでのJDKのInstall|技術的雑談-LinuxでのJDKのInstall]]

*[[Tomcat5.5をLinuxにInstallする|技術的雑談-Tomcat5.5をLinuxにInstallする]]

*[[mod_jkを使ってTomcatとhttpdを連携する|技術的雑談-mod_jkを使ってTomcatとhttpdを連携する]]

*[[複数のTomcatを立ち上げてmod_jk経由でロードバランスさせる|技術的雑談-複数のTomcatを立ち上げてmod_jk経由でロードバランスさせる]]

*[べたつきません|http://t-katochin.air-nifty.com/nongreasy/2005/08/post_aa27.html]:大変参考にさせていただきましたm(__)m

!!履歴
2007/01/18 -- 初版

[[技術的雑談]]へ戻る

!!突っ込み
*dddddddddddddddd - dddddddd (2012年01月20日 17時52分36秒)

{{comment}}

[[技術的雑談]]へ戻る

{{trackback}}

[[技術的雑談]]へ戻る