Cosminexus V9 アプリケーションサーバ 機能解説 互換編
メモリセッションフェイルオーバ機能を使用するアプリケーションを開発する場合に,留意する点について説明します。
セッションフェイルオーバ用フィルタは,サーブレットフィルタとして提供されます。セッションフェイルオーバ用フィルタは,ほかのサーブレットフィルタよりも前に呼び出される必要があります。HTTPレスポンス圧縮フィルタ,およびユーザ作成のフィルタよりも前に配置してください。フィルタの組み込みについては,マニュアル「アプリケーションサーバ 機能解説 基本・開発編(Webコンテナ)」の「2.9.2 フィルタ連鎖の推奨例」を参照してください。
メモリセッションフェイルオーバ機能を有効にしたアプリケーションでは,セッションを作成すると必ずグローバルセッションIDが発行され,グローバルセッション情報を使用しないサーブレットまたはJSPであっても,「グローバルセッション情報が存在しない」という情報がSFOサーバに冗長化されます。
JSPでは,デフォルトでHttpSessionオブジェクトが作成されます。メモリの使用量や,SFOサーバとの通信による負荷を考慮し,セッションを必要としないJSPでは明示的にHttpSessionオブジェクトを作成しない設定にしてください。HttpSessionオブジェクトを作成しない設定には,pageディレクティブのsession属性を使用してください。
HTTPセッションのセッション管理には,グローバルセッション情報を使用するようにしてください。
メモリセッションフェイルオーバ機能では,障害発生時にグローバルセッション情報は引き継げますが,HTTPセッションは新しく作成されます。このため,HTTPセッションのセッションIDはグローバルセッション情報の引き継ぎの前後で異なります。したがって,HTTPセッションのセッションIDを基に制御を実行するアプリケーションは,グローバルセッション情報を基に制御を実行するように変更する必要があります。
メモリセッションフェイルオーバ機能を使用するアプリケーションでは,障害発生時にグローバルセッション情報の引き継ぎ処理や,書き換え可能グローバルセッション情報の削除処理が発生します。
アプリケーションでは,これらを想定した処理を実装する必要があります。
J2EEサーバやWebサーバに障害が発生すると,リクエストが別のJ2EEサーバに転送されて,セッション情報が引き継がれます。アプリケーションが引き継ぎ先のJ2EEサーバで問題なく業務を続けるためには,必要な情報をすべてグローバルセッション情報として設定しておく必要があります。
グローバルセッション情報として設定できる情報については,「6.4.2 グローバルセッション情報」を参照してください。また,グローバルセッション情報の引き継ぎについては,「6.4.5 サーバの状態とグローバルセッション情報の引き継ぎ」を参照してください。
HttpSessionオブジェクトに同じオブジェクトが複数登録されていた場合に,引き継ぎ後のHttpSessionオブジェクトに登録されるオブジェクトが異なるので,注意が必要です。
図6-30 一つのHttpSessionオブジェクトに同じオブジェクトが複数登録されている場合の引き継ぎの例
この図では,J2EEサーバ1上のHttpSessionオブジェクトに,java.lang.Stringクラスのオブジェクトであるセッション情報Bが複数登録されています。J2EEサーバ1で障害が発生して,J2EEサーバ2へセッション情報が引き継がれた場合,J2EEサーバ2上のHttpSessionオブジェクトには,複数登録されていたセッション情報Bが,それぞれ別のセッション情報B-1とセッション情報B-2として生成されます。セッション情報B-1およびセッション情報B-2は,インスタンスは異なりますが,内容は同じです。図6-31 異なるHttpSessionオブジェクトに同一のオブジェクトが登録されている場合の引き継ぎの例
この図では,J2EEサーバ1上のHttpSessionオブジェクト1およびHttpSessionオブジェクト2で,同一のオブジェクトのセッション情報Cを共有しています。J2EEサーバ1で障害が発生して,J2EEサーバ2へセッション情報が引き継がれた場合,J2EEサーバ2上のHttpSessionオブジェクト1およびHttpSessionオブジェクト2には,共有されていたセッション情報Cが,それぞれ別のセッション情報C-1とセッション情報C-2として生成されます。セッション情報C-1およびセッション情報C-2は,インスタンスは異なりますが,内容は同じです。SFOサーバに障害が発生した場合など,書き換え可能グローバルセッション情報の削除が発生したとき,HttpSessionオブジェクトには読み込み専用グローバルセッション情報とグローバルセッション情報でないセッション情報が残ります。
リクエスト処理を実行する前に,書き換えグローバルセッション情報が削除されていないかどうかを確認する処理を実行して,削除されている場合には適切な処理を実行してください。
例えば,グローバルセッション情報が次のように設定されている場合があります。
この場合,書き換え可能グローバルセッション情報が削除されると,HttpSessionオブジェクトに登録されたセッション情報の内容はログイン直後の状態に戻ります。この状態から業務を再開するためには,オブジェクトを再作成する処理や,javax.servlet.http.HttpServletResponseインタフェースのsendRedirectメソッドを使用してログイン直後のページに戻す処理などが必要になります。
J2EEアプリケーション内での書き換え可能グローバルセッション情報が削除されているかどうかは,HttpSessionオブジェクトに登録した書き換え可能グローバルセッション情報があるかどうかで確認できます。確認した結果,あるはずの書き換え可能グローバルセッション情報がなくなっていた場合,書き換え可能グローバルセッション情報が削除されたと判断できます。
HTTPセッションを破棄するアプリケーション内でレスポンスのコミットを実行しても,クライアント上のグローバルセッションIDのHTTP Cookie情報は削除されません。この場合,コミット後にリクエストを送信するとき,グローバルセッションIDがリクエストヘッダのCookieとして付加されて,J2EEサーバ,SFOサーバのメッセージログに次のログメッセージが出力されます。
ただし,これらのメッセージが出力された場合も,J2EEサーバ,SFOサーバでの実際のリクエスト処理,およびメモリセッションフェイルオーバ機能への影響はありません。なお,クライアント上のグローバルセッションIDのHTTP Cookie情報を削除する処理は,この時点で実行されます。以降のリクエスト処理ではこのHTTP Cookieは付加されません。
また,javax.servlet.http.HttpServletResponseインタフェースのsendRedirectメソッドを使用した場合も,レスポンスがコミットされて,リダイレクト先アドレスへのアクセス時にKDJE34234-Wのメッセージが出力されます。このとき,リダイレクト先アドレスがFORM認証を使用しているページへのアドレスであった場合,J2EEサーバのメッセージログにはKDJE34234-Wのメッセージではなく,KDJE34229-Wのメッセージ(出力レベル:Warning)が出力されます。ただし,この場合も,認証機能およびメモリセッションフェイルオーバ機能への影響はありません。
障害発生時に認証情報を引き継ぐ場合は,Basic認証によって認証処理をする必要があります。Basic認証を使用すると,認証されたJ2EEサーバと異なるJ2EEサーバにリクエストが振り分けられた場合でも,再度認証する必要はありません。グローバルセッション情報は正常に引き継がれ,業務を続けられます。
サーブレットAPIで定義されているフォーム認証によって認証処理をしている場合,認証されたJ2EEサーバと異なるJ2EEサーバにリクエストが振り分けられた場合は,認証情報が引き継がれていても,再度認証が必要です。
Basic認証およびForm認証については,マニュアル「アプリケーションサーバ 機能解説 セキュリティ管理機能編」の「6.2 DDの設定によるWebコンテナのユーザ認証」を参照してください。
メモリセッションフェイルオーバ機能を使用する場合と,使用しない場合とで動作が変わるサーブレットAPIがあります。次に,メモリセッションフェイルオーバ機能によって動作に変更があるAPIおよび注意点を示します。
表6-15 メモリセッションフェイルオーバ機能と関係するサーブレットAPI
項番 | クラス名またはインタフェース名※1 | API名 | 注意点 |
---|---|---|---|
1 | ServletContext | getAttributeNames | HTTP Cookieによるグローバルセッション制御が有効な場合に動作が変わります。グローバルセッションIDに使用するHTTP Cookie名称をサーブレットコンテキストに属性として登録します。グローバルセッションIDは,セッションフェイルオーバ用フィルタ開始時に初期化パラメタに設定されたIDです。getAttributeNamesで取得できる属性名にこの属性の名称が含まれます。セッションフェイルオーバ用フィルタが登録する属性については,「6.11.3 アプリケーションを実行するときに追加される属性」を参照してください。 |
2 | ServletContextAttributeListener | attributeAdded | HTTP Cookieによるグローバルセッション制御が有効な場合に動作が変わります。グローバルセッションIDに使用するHTTP Cookie名称をサーブレットコンテキストに属性として登録するために,javax.servlet.ServletContextAttributeListenerクラスのattributeAddedメソッドが呼び出されます。グローバルセッションIDは,セッションフェイルオーバ用フィルタ開始時に初期化パラメタに設定されたIDです。サーブレットコンテキストに登録する属性については,「6.11.3 アプリケーションを実行するときに追加される属性」を参照してください。 |
3 | HttpServletRequest | getCookies | HTTP Cookieによるグローバルセッション制御が有効な場合に動作が変わります。グローバルセッションが発行されると,グローバルセッションIDがCookieヘッダにセットされます。HTTP Cookieの名称は,GIDCookieNameパラメタに指定した値です。 |
4 | getHeader | ||
5 | getHeaderNames | ||
6 | getHeaders | ||
7 | getSession | HTTPセッション作成時に,J2EEサーバのHTTPセッション数に余裕がある場合でも,SFOサーバでグローバルセッション数が上限に達すると,IllegalStateException例外が発生します。 | |
8 | HttpServletResponse | encodeRedirectURL | URL書き換えによるグローバルセッション制御が有効な場合に動作が変わります。グローバルセッションIDをURLに含めてエンコードします。グローバルセッションIDは,HTTPセッションIDとともにエンコードされます。この処理は必要に応じて実行されます。 |
9 | encodeURL | ||
10 | encodeRedirectUrl※2 | ||
11 | encodeUrl※2 | ||
12 | HttpSession | getAttribute | 書き換え可能グローバルセッション情報の削除処理が発生すると,Webコンテナによって属性が追加されます。Webコンテナが追加する属性については,「6.11.3 アプリケーションを実行するときに追加される属性」を参照してください。 |
13 | getAttributeNames | ||
14 | getCreationTime | 引き継ぎが発生すると,引き継ぎ処理によってHttpSessionオブジェクトが作成されるため,引き継ぎ発生前と異なる値が返されます。 | |
15 | getId※3 | ||
16 | getLastAccessedTime | 引き継ぎ発生後,初回のリクエスト時には前回アクセスの時刻を返すことができません。 | |
17 | isNew※4 | 引き継ぎによって,HttpSessionオブジェクトが作成されると,戻り値が「true」となります。 | |
18 | HttpSessionAttributeListener | リスナについては,「6.9.4 リクエスト実行時の処理」を参照してください。 | |
19 | HttpSessionBindingListener | ||
20 | HttpSessionListener | ||
21 | HttpServletRequestWrapper | 動作については,javax.servlet.http.HttpServletRequestインタフェースの動作を参考にしてください。 |
JSPで<jsp:useBean>タグを使用する時,scope属性を"session"とすることで,JavaBeansがHttpSessionオブジェクトの属性として登録されます。
<jsp:useBean>タグのscope属性を"session"とする場合には,次の設定が必要になります。
All Rights Reserved. Copyright (C) 2012, 2015, Hitachi, Ltd.