GlassFishV2.1のクラスタでおこる、ふたつのバグと回避策

GlassFishのバグを見つけたので詳細報告。OSS版でも同じ現象が起こるかもしれない。

現象詳細
GlassFish V2.1系でインメモリーレプレケーションでクラスタを構築、ロードバランサープラグインを使いApacheなどのWebServerからロードバランシングを行う。このとき、セッション内容とスティッキー性が失われる場合がある。

■セッションの消失
   新しいSessionIDが発行され、それまでのセッション内容が保持できない
   F5キーを押下し続けて連続でリロードを行った場合に再現される
■ スティッキー性の消失
  同一クライアント、同一セッションでアクセス中に接続されているインスタンスが固定されない

上記、現象が併発した場合、同一SessionIDにもかかわらずインスタンスごとに違う内容のセッションを保持しているケースも確認された。

原因
■ セッションの消失

複数のクライアントから同時に同じSessionIDへアクセスした場合に、SessionIDが変わることがある。F5押下(KeyPress-Keep)による連続リロードや複数のAjaxによる同一SessionIDへアクセスした場合などに発生する。

Cookie情報であるJSESSIONIDVERSIONがセッション情報のキャッシュを管理している。通常、同一セッションへのアクセスごとに連続した値(プラス1づつカウントアップ)を返すが、同時に同じセッションIDへアクセスした場合に、不正な値を返す場合がある。

JSESSIONIDVERSIONが不正な値を返した場合に、それまでのSessionIDが無効と判断され新しいSessionIDが発行される。

■ スティッキー性の消失

Cookie情報のうちJROUTEの値が稼動しているインスタンスの識別子となる。アクセスしているインスタンスが停止した場合、稼動中のインスタンスに対応する識別子に変更される。

JROUTEを書き換えるのはロードバランサプラグインが行うが、設定ファイルであるloadbalancer.xmlがCookie情報の書き換え禁止するオプションで出力されている。アクセス中のインスタンスが停止した場合、JROUTEが設定されずスティッキー性が失われる。

回避策

■セッションの消失への対応
relaxCacheVersionSemanticsを設定する。ただし、9.1U2P05以降でのみ有効

配備するsun-web.xmlに非公開パラメータである以下を記述
  <session-config>
    <session-manager persistence-type=”replicated”>
      <manager-properties>
        <property name=”relaxCacheVersionSemantics” value=”true”/>
      </manager-properties>
この設定によりJSESSIONIDVERSIONが正しい値を返すようになる。

実は、このrelaxCacheVersionSemanticsは非公開パラメータ。マニュアルに載せて欲しいとは言っておいたがどうなるのだろう。

■ スティッキー性の消失への対応

一時的な回避策としてloadbalancer.xmlに以下を記述する(falseからtrueに変更)。
または、設定を削除する。

 <property name=”rewrite-cookies” value=”true”/>

この設定によりアプリケーションサーバでCookie情報(JROUTE)の書き込みを許可する。ただし、現在、Oracleが対応しているバグ修正では、GlassFishでJROUTEへの書き込みを行うため、修正版のリリース後は、上記設定は不要になるはず。

V3での対応は不明だがお願いはしておいた。たぶん、ちゃんと対応してくれるはず。
オマケ GlassFishのコードを簡単にカスタマイズする

GlassFishで使用されている同名クラスを作成して、jarにまとめる。

GlassFishの管理GUIからConfiguration->server-config->JVM Settings->Path Settingsへと進む。Classpath Prefixにjarファイルを設定後、GlassFishを再起動

オリジナルのコードが既存のJavaクラスに上書きして使用される。

大学院ではロボットを研究しているんだ

中間発表のスライドをUPしたよ。

ついでにテーマ発表のスライド。
半年前から進展しているんだろうか……