seasar+sastrutsの環境でtomcatのセッションレプリケーションを使うと、
サーバが複数台ある時に問題が生じたので、その内容と対策を書く。
目標
上図のようなサーバ構成があるとする。
両方のサーバでセッションを共有させることで、
もし102,103のどちらかのサーバがダウンしたとしても問題なく動作させるようにする。
セッションが共有できていないと、
仮に102でセッションが作られたユーザは、
103サーバにリクエストが送られた途端にセッション情報がないのでエラーになってしまう。
問題
本番反映時にセッションレプリケーションの動作確認を行ってみたら、ページを読み込むたびに「表示」→「エラー」を繰り返していた。
次に102,103のログを見ながらページを読み込むと、
ある特定のサーバへのリクエストのみエラーが起こっていて、
正常にセッションレプリケーションができていないのではないかと推測。
調査を行うと、sastrutsのアノテーションを利用して、
必要な情報を格納するDTOクラスをセッションに登録した場合には、
tomcatのセッションレプリケーションができないということがわかった。
http://ml.seasar.org/archives/seasar-user/2009-July/017893.html
@Component(instance = InstanceType.SESSION) //←コイツ public class SampleDto implements Serializable { private static final long serialVersionUID = 1L; public String name; }
対策
対策は以下の参考URLにあるように2つあるのだけど、- セッションオブジェクトに直接setAttribute
http://ml.seasar.org/archives/seasar-user/2009-July/017887.html - seasarのdbsession.diconを用いたDBセッションレプリケーション
http://s2container.seasar.org/2.4/ja/dbsession.html
RequestUtil.getRequest().getSession().setAttribute("sampleDto", sampleDto);
この対応で本番環境でもセッションレプリケーションが実現できた!!
※開発段階でサーバを2台用意しセッションレプリケーションのテストができる状態にできるのであれば、
事前に確認してリスクを軽減でき、本番でセッションレプリケーションの問題が生じたときにも調査が容易になる。
備考
ついでにtomcatのセッションレプリケーションの設定方法も書く・httpd.conf
<Proxy balancer://cluster/> BalancerMember ajp://xxx.xxx.xxx.xxx:8009 route=MAP1 loadfactor=10 keepalive=on BalancerMember ajp://xxx.xxx.xxx.xxx:8009 route=MAP2 loadfactor=10 keepalive=on </Proxy>
・server.xml
/*以下は192.168.0.102の設定。192.168.0.103はjvmRoute=MAP2, tcpListenAddress=192.168.0.103とする。*/ <Engine name="Catalina" defaultHost="localhost" jvmRoute="MAP1"> <Host name="localhost" appBase="webapps" /> <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" managerClassName="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" useDirtyFlag="true" printToScreen="true"> <Membership className="org.apache.catalina.ha.mcast.McastService" mcastAddr="228.0.0.4" mcastPort="45564" mcastFrequency="500" mcastDropTime="3000"/> <Receiver className="org.apache.catalina.ha.tcp.ReplicationListener" tcpListenAddress="192.168.0.102" tcpListenPort="4001" tcpSelectorTimeout="100" tcpThreadCount="2"/> <Sender className="org.apache.catalina.ha.tcp.ReplicationTransmitter" replicationMode="pooled"/> <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=".*\.gif;.*\.js;.*\.jpg;.*\.htm;.*\.html;.*\.txt;.*\.xhtml"/> <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" tempDir="/tmp/war-temp/" deployDir="/tmp/war-deploy/" watchDir="/tmp/war-listen/" watchEnabled="false"/> </Cluster> </Engine>
・web.xml
<!-- Session Clustering --> <distributable />
0 コメント:
コメントを投稿