サーブレットエンジンモードでは,Webコンテナ上のアプリケーションの更新を検知し,更新したアプリケーションをリロードする機能を備えています。この機能によって,Webコンテナサーバを再起動することなく,デプロイ済みのサーブレットやJSPを動的に入れ替えることができます。この機能は,Webアプリケーション開発時のテストを支援する機能として利用します。
リロード機能には,次の二つがあります。
- Webアプリケーションのリロード機能
Webコンテナサーバ起動中にWebアプリケーションを更新すると,WebコンテナはWebアプリケーションが更新されたことを検知し,更新後のWebアプリケーションをリロードします。
- JSPファイルの再コンパイル機能
Webコンテナサーバ起動中にJSPを更新すると,WebコンテナはJSPが更新されたことを検知し,更新後のJSPを再コンパイルします。
これらの機能によって,Webコンテナサーバにロード済み※のサーブレットまたはJSPを,Webコンテナサーバ起動中に更新後のサーブレットまたはJSPに置き換えができます。
- 注※
- Webコンテナサーバの起動後にアクセスされたサーブレット/JSP,またはweb.xmlの<load-on-startup>タグに指定されているサーブレット/JSPを指します。
- 更新検知の対象となるファイル
Webアプリケーションのリロード機能およびJSPファイルの再コンパイル機能の対象は,webapps下にデプロイされたWebアプリケーションのディレクトリ下のファイルです。
webappsは,次の場所にあります。
- Windowsの場合
<Cosminexusのインストールディレクトリ>\CC\web\containers\<サーバ名称>\webapps
- UNIXの場合
/opt/Cosminexus/CC/web/containers/<サーバ名称>/webapps
なお,WARファイルのコピーでのデプロイの場合,Webコンテナサーバ起動後に展開されたディレクトリ内のファイルが対象です。
Webアプリケーションのリロードと,JSPファイルの再コンパイルについて次に示します。
- <この項の構成>
- (1) Webアプリケーションのリロード
- (2) リロードの動作に関する設定
- (3) JSPファイルの再コンパイル
Webアプリケーションのリロードの条件について説明します。
Webコンテナサーバ起動後,更新検知対象のファイルが次に示す条件でリロードされます。
表C-2 リロードの条件
更新検知対象のファイル種別 |
リロードの条件 |
- Windowsの場合
- WEB-INF\classesディレクトリ下のクラスファイルおよびリソースファイル(java.util.ResourceBundleによってロードされたファイルなど)
- UNIXの場合
- WEB-INF/classesディレクトリ下のクラスファイルおよびリソースファイル(java.util.ResourceBundleによってロードされたファイルなど)
|
- ロード時の更新日時と異なる場合
- ロードされたファイルが削除された場合
|
- Windowsの場合
- WEB-INF\libディレクトリ下のJARファイル
- UNIXの場合
- WEB-INF/libディレクトリ下のJARファイル
|
- ロード時の更新日時と異なる場合
- JARファイルが追加された場合
- JARファイルが削除された場合
|
Webアプリケーションの更新を検知して,リロードするまでの流れを次の図に示します。
図C-1 Webアプリケーションの更新検知からリロードまでの動作
- Webアプリケーションを更新する
- WebコンテナがWebアプリケーションの更新を検知する
Webコンテナは,設定した間隔でWebアプリケーションが更新されているかどうかチェックします。この間隔は,更新検知のインターバルで設定します。詳細については,「(2)(a) 更新検知のインターバル」を参照してください。
また,更新を検知してから,手順3.の処理を実施するまでのインターバルを設定できます。インターバルの設定については,「(2)(b) リソース更新用インターバル」を参照してください。
- 新規リクエストを実行待ち状態にする
なお,処理中のリクエストはそのまま実行します。
デフォルトでは,新規リクエストを実行待ちにしますが,処理中のリクエストの処理が終わってから,新規リクエストを実行待ちにすることもできます。この場合,リロード遅延実行の設定が必要になります。リロード遅延実行については,「(2)(c) リロード遅延実行(任意)」を参照してください。リロード遅延実行の設定は任意となります。
- Webアプリケーションの終了処理をする
終了処理では次の処理が実行されます。
- リロード前のクラスローダにローディングされたサーブレットのインスタンスが破棄されます。サーブレットがdestroyメソッドを実装している場合,destroyメソッドが実行されます。また,JSPファイルから生成されたサーブレットのインスタンスも破棄されます。この際,JSPファイルが,jspDestroyメソッドを実装している場合,jspDestroyメソッドが実行されます。
- javax.servlet.ServletContextに登録されたオブジェクトは破棄されます。
- セッション情報(javax.servlet.http.HttpSessionオブジェクトに登録したオブジェクト)をシリアライズ※し,セッション情報ファイルに出力する
セッション情報を引き継ぐかどうかを設定できます。セッション情報を引き継ぎたい場合に指定してください。詳細については,「(2)(d) リロード時のセッション引き継ぎ(任意)」を参照してください。
- Webアプリケーション単位のクラスローダを新規に作成する
Webアプリケーションのリロード処理が実行されると,Webアプリケーション単位のクラスローダが新たに作成され,リロード後のリクエスト処理で使用されます。すでにロードされているサーブレットについては,destroyメソッドが実行され,インスタンスを破棄します。
- セッション情報ファイルからセッション情報を読み込み,デシリアライズ※する
セッション情報ファイルからセッション情報を読み込み,リロード後のクラスローダ上でデシリアライズします。セッション情報の引き継ぎを設定している場合だけ実施されます。
- セッション情報ファイルを削除する
セッション引き継ぎを指定している場合だけ実施されます。
- Webアプリケーションの開始処理をする
リロード後は,初回アクセス時に更新後のサーブレットのインスタンスが作成され,initメソッドが実行されます。
- リクエスト処理を再開する
3.で実行待ちにしていたリクエストの処理を再開します。
- 注※
- シリアライズ処理,およびデシリアライズ処理の時間は,リロードを実行しているWebアプリケーション上で生成されたセッション数,javax.servlet.http.HttpSessionオブジェクトに登録したオブジェクトの容量などに依存します。
アプリケーションの更新検知とリロード機能は,デフォルトの設定では実行されません。必要に応じて実行するように設定してください。
この機能では,次の動作をカスタマイズできます。
- 更新検知のインターバル
- リソース更新用インターバル
- リロード遅延実行(任意)
- リロード時のセッション引き継ぎ(任意)
リロードの動作に関する設定は,Webコンテナサーバのプロパティ,またはWebコンテナ上で動作するWebアプリケーションプロパティとして設定します。アプリケーションの更新検知とリロードの設定については,マニュアル「Cosminexus システム構築ガイド」を参照してください。
Webアプリケーションの更新を検知する間隔を設定できます。更新検知は,デーモンスレッドによって実行されます。デフォルトでは1秒間隔となっています。
更新検知インターバルの値を大きくすると,構成ファイルを監視する間隔が長くなり,ファイル更新後のリロードの反映が遅くなります。また,値を小さくすると,リロードの反映が早くなります。
- ポイント
- 更新検知の対象となるファイル数が増えると,更新検知処理のオーバーヘッドが大きくなり,CPU使用率が高くなります。このような場合は,更新検知インターバルを変更することによって,性能への影響が小さくなります。更新検知インターバルの値は大きくすることをお勧めします。
Webアプリケーションの更新を検知してから,処理中のリクエスト数の監視を実施するまでの時間を設定できます。
Webコンテナは,ファイル(リソース)の更新を検知すると,更新するファイルをコピーし,処理中のリクエスト数の監視を開始します。処理中のリクエストの処理が完了すると,コピーしたファイルをロードします。ファイルの容量が大きい場合,ネットワークを経由した場合や,ファイルが複数ある場合には,ファイルコピーなどの処理時間が長くなることがあります。このとき,ファイルコピーが完了する前に処理中のリクエストがなくなると,ファイルコピー中にロードが開始されて,ロードに失敗するおそれがあります。これを回避するため,ファイルコピーに掛かる時間を考慮してコピーが完了してからロードが開始されるように,構成ファイルの更新を検知してから処理中のリクエスト数の監視を開始するまでの時間をリソース更新用インターバルとして設定しておくことができます。
- ポイント
- リソース更新用インターバルには,実際に掛かるコピー時間にゆとりを持たせた時間を設定することをお勧めします。
- 複数のファイルを同時に更新する場合,複数のファイルの更新に掛かる時間を算出して,設定してください。
ファイル(リソース)の更新を検知してから,リロードを開始するまでの時間を設定できます。リロード遅延実行の時間を設定している場合に,Webアプリケーションの更新を検知すると,リロードの開始を遅延実行に指定した時間まで遅らせます。指定した時間内に処理中のリクエストがなくなるか,または指定した時間がくると,アプリケーションのサービスを停止してリロードを開始します。これによって,処理中のリクエストの実行待ち時間を減らすことができるため,アプリケーションのサービス停止期間を最小限にできます。
なお,デフォルトでは,リロード遅延実行が設定されていません。デフォルトでは次のような動作となります。
- Webコンテナがリソースの更新を検知すると,アプリケーションのサービスを停止する
- リクエストを次のように処理する
- 新規のリクエスト:実行待ちにする
- 処理中のリクエスト:すべてのリクエストを処理する
- 処理中のリクエストの処理が完了すると,リロードが実施される
リロードの遅延実行が設定されていないと,アプリケーションのサービス停止の期間が長くなります。これを回避するため,リロード遅延実行を設定することをお勧めします。
リロード遅延実行を設定した場合と設定しない場合の,アプリケーションのサービス停止期間の違いを,次の図に示します。
図C-2 アプリケーションのサービスの停止期間の違い
Webアプリケーションのリロード実行前に生成したセッション情報を,リロード後も継続して利用するかどうかを設定できます。これによって,リロード前にjavax.servlet.http.HttpSessionオブジェクトに登録されているオブジェクトを,リロード後も引き続き利用できるようになります。セッションの情報は,シリアライズされてセッション情報ファイルに出力されます。セッション情報ファイルは,リロード処理開始時に作成されます。そして,リロード後にセッション情報がクラスローダ上でデシリアライズされ,セッション情報ファイルはリロード処理完了時に削除されます。
なお,セッション引き継ぎ機能を使用しない場合,リロード処理が実行されるとセッション情報はすべて失われます。
Webアプリケーションのリロード機能を使用する際の,注意について説明します。
●リロード機能の使用に関する注意
- Webアプリケーションのリロード機能を使用する場合,web.xmlに<error-page>タグを定義しないでください。
- Webアプリケーションのリロード機能を使用する場合,WebアプリケーションからJNIを利用することはできません。リロード処理ではWebアプリケーション単位のクラスローダを置き換えますが,JNIの仕様では,異なるクラスローダ上で同じネイティブライブラリをロードできないという制限があるためです。
- Webアプリケーションのリロード機能は,Webアプリケーション単位のクラスローダを入れ替えることによって,Webコンテナ起動中のWebアプリケーションの入れ替えを実現しています。そのため,リロード後にリロード前のWebアプリケーション単位のクラスローダ,またはWebアプリケーション単位のクラスローダでロードされたクラスが参照されるとメモリリークが発生します。
次に,該当する場合を示します。
- スレッドの生成
スレッドはコンテキストクラスローダを保持しますが,デフォルトでは親スレッドのコンテキストクラスローダを保持します。Webアプリケーション実行時のスレッドは,Webアプリケーション単位のクラスローダをコンテキストクラスローダとしているため,生成されたスレッドはWebアプリケーション単位のクラスローダをコンテキストクラスローダとします。そのため,リロード後も該当スレッドが存在すると,リロード前のWebアプリケーション単位のクラスローダが解放されないでメモリリークが発生します。
- java.lang.Threadクラスまたはその派生クラスのインスタンス生成
java.lang.Threadクラスまたはその派生クラス(以降,スレッドクラス)のインスタンスを作成すると,所属するスレッドグループから該当スレッドクラスのインスタンスが参照されます。スレッドグループからの参照は,スレッドの実行を終了(runメソッドの完了)すると解放されます。そのため,Webアプリケーション内でスレッドクラスのインスタンスを生成し,runメソッドを実行しなかった場合は,該当スレッドクラスのインスタンスが解放されません。また,スレッドはコンテキストクラスローダとしてWebアプリケーション単位のクラスローダを保持しているため,Webアプリケーション単位のクラスローダが解放されないでメモリリークが発生します。
- スレッドローカル変数の使用
Webコンテナではリクエストを処理するスレッドはプールされていて,Webコンテナ終了時まで終了しません。そのため,スレッドローカル変数にWebアプリケーションに含まれるクラスのインスタンスを格納すると,メモリリークが発生します。
- Webアプリケーション外からの参照
usrconf.cfg(Webコンテナサーバ用オプション定義ファイル)のweb.add.class.pathキーで指定したクラスパスに存在するクラスは,システムクラスローダからロードされます。リロード実行時に該当クラスはアンロードされません。
このため,該当クラスのクラス変数からWebアプリケーション単位のクラスローダ,またはWebアプリケーション単位のクラスローダでロードされたクラスを参照すると,メモリリークが発生します。
- Webアプリケーションのリロード機能と,JSPの再コンパイル機能を併用する場合,次のことに注意してください。
- JSPファイルだけを更新した場合,Webアプリケーションのリロードは実行されません。
- JSPファイルの再コンパイルが実行されている場合には,リロード処理でのJSPの再コンパイルは停止されることがあります。この場合,JSPファイルの再コンパイルは,リロード完了後の該当するJSPに対して初めてアクセスするときに実行されます。また,web.xmlの<load-on-startup>タグに該当するJSPファイルが指定されている場合は,リロード処理内のWebアプリケーションの初期化処理で実行されます。
●リソースの更新に関する注意
- 次の場合にはメモリ不足が発生するおそれがあるため,リソースの更新はリクエストのピーク時など負荷の高いときを避けて実施してください。
- リロードの処理は,クラスローダを再作成してクラスをロードし直すため,メモリを多く消費します(ただし,消費するメモリ使用量は,Webアプリケーションの実装に依存します)。そのため,例えば,複数のWebアプリケーションで,同時にリロード処理を繰り返すと,メモリ不足が発生するおそれがあります。
- リロード処理によって不要になったリソースがJavaVMから解放されるタイミングは,JavaVMのガーベージコレクションの実行のタイミングに依存します。リクエストのピーク時など,負荷が高いときにリロードを繰り返すと,ガーベージコレクションを実行するタイミングがなく,メモリ不足が発生するおそれがあります。
- 複数のリソースを更新する場合,リソース更新用インターバルに,複数のリソースの更新(ファイルコピー)に掛かる時間を指定してください。なお,いったん,リソースを更新したら,リロード処理が完了する前に別のリソースを更新しないようにしてください。
- ロード済みのリソース(ファイル)を削除した場合もWebアプリケーションに対する変更と判断されるため,リロードが実行されます。このため,不用意にリソースを削除しないよう,注意してください。
●リロード処理実行時の注意
- Webアプリケーションのリロード処理が実行されると,Webアプリケーション単位のクラスローダを置き換えるため,リロード前に作成されたインスタンスをリロード後のサーブレットから使用できません。
- 更新前のサーブレットがjavax.servlet.ServletContextに登録したオブジェクトはクリア(削除)されます。更新前のサーブレットが生成したセッションは破棄され,更新後のサーブレットにアクセスすると新しいセッションが生成されます。さらに,Webアプリケーションのリロード時には,そのときロードされているJSPもリロードされます。
- Webアプリケーションのリロード機能を使用すると,更新検知処理のためのオーバーヘッドが発生し,監視対象のファイル数の増加に伴ってオーバーヘッドが大きくなるため,更新検知間隔を変更して性能への影響を小さくする必要があります。
- リロード処理中に,cjstopwebコマンドでWebコンテナサーバに対して終了要求を発行した場合は,次のように動作します。
- リロード処理内のWebアプリケーションの初期化処理の開始前の場合
リロード処理を中断し,終了処理が実行されます。
- リロード処理内のWebアプリケーションの初期化処理の開始後の場合
リロード処理完了後に,Webコンテナサーバの終了処理が実行されます。このとき,リロード処理による実行待ちのリクエストはエラーになります。
●リロードの処理時間に関する注意
リロード処理時間は,Webアプリケーションの実装に大きく依存します。このため,次の点に注意が必要です。
- セッション情報の容量は,シリアライズ処理時間,デシリアライズ処理時間に大きく影響します。シリアライズ対象となるセッション情報は,必要十分な容量にしてください。
- リロード処理では,Webアプリケーションの終了処理,初期化処理が実行されます。終了処理,初期化処理が長い場合,リロードの処理時間も長くなり,Webアプリケーションのサービス停止期間にも影響があるため注意してください。ただし,リロード処理で初期化処理が実行されるのは,web.xmlの<load-on-startup>タグを設定したサーブレットやJSPだけです。<load-on-startup>タグを設定していないサーブレットやJSPの初期化処理は,リロード完了後の初回アクセス時に実行されます。
●セッション引き継ぎ機能を使用する場合の注意
- リロード時のセッション引き継ぎ機能を使用する場合,javax.servlet.http.HttpSessionに登録するセッション情報は,シリアライズできるオブジェクトである必要があります。
- HttpSessionオブジェクトに登録したオブジェクトから参照するオブジェクトは,transientで宣言されているか,またはシリアライズできるオブジェクトである必要があります。以降,参照するオブジェクトも同様です。シリアライズできるオブジェクトについての詳細は,J2SEの仕様書を参照してください。
- セッション情報としてシリアライズできないオブジェクトを登録した場合は,エラーが発生します。エラーの内容はオブジェクトによって異なります。
- javax.servlet.http.HttpSessionに登録したオブジェクトの場合
HttpSessionオブジェクトに登録したオブジェクトが,シリアライズできないオブジェクトである場合,該当するオブジェクトだけを破棄します。破棄されたオブジェクトは,リロードが完了したあとに使用することはできません。また,該当するオブジェクトが,javax.servlet.http. HttpSessionBindingListenerインタフェースを実装していても,Webコンテナからアンバインドされたイベントは通知されません。
- javax.servlet.http.HttpSessionに登録したオブジェクトから参照されるオブジェクトの場合
HttpSessionに登録したオブジェクトから参照されるオブジェクトがシリアライズできないオブジェクトの場合,すべてのセッション情報が破棄されます。HttpSessionに登録したオブジェクトから参照されるオブジェクトが,HttpSessionに登録したオブジェクトの場合も同様に,すべてのセッション情報が破棄されます。
- シリアライズ対象となるセッションに登録したオブジェクトのクラス,およびそこから参照されるオブジェクトのクラスを,デシリアライズできない構成に更新してリロードを実行した場合,セッションのデシリアライズに失敗します。デシリアライズに失敗すると,Webアプリケーション上のすべてのセッション情報が破棄されるので注意してください。
WebコンテナにロードされたJSPファイルの更新日時がロード時と異なる場合,再コンパイルされるように設定できます。ただし,JSPファイルから生成されたJavaファイル,またはクラスファイルを更新しても,再コンパイルの対象にはなりません。
JSPの再コンパイル機能は,デフォルトの設定では実行されません。必要に応じて実行するように設定してください。
この機能では,次の動作をカスタマイズできます。
- 更新検知のインターバル
- JSPファイル更新用インターバル
JSPファイルの再コンパイルに関する設定は,Webコンテナサーバのプロパティ,またはWebコンテナ上で動作するWebアプリケーションプロパティとして設定します。アプリケーションの更新検知とリロードの設定については,マニュアル「Cosminexus システム構築ガイド」を参照してください。
JSPファイルの更新を検知する間隔を指定できます。更新検知は,デーモンスレッドによって実行されます。デフォルトでは1秒間隔となっています。
- ポイント
- 更新検知の対象となるファイル数が増えると,更新検知処理のオーバーヘッドが大きくなり,CPU使用率が高くなります。このような場合は,更新検知インターバルを変更することによって,性能への影響が小さくなります。更新検知インターバルの値は大きくすることをお勧めします。
JSPファイル更新用インターバルとは,JSPファイルの更新を検知してから,JSPファイルをコンパイルするまでの間隔を指します。
- 設定の指針
- JSPファイル更新用インターバルには,実際にファイルのコピーに掛かる時間よりも長い時間を設定することをお勧めします。
- 複数のファイルを同時に更新する場合,複数のファイルの更新に掛かる時間を算出して,設定してください。
- JSPファイルの再コンパイル機能を使用すると,更新検知処理のためのオーバーヘッドが発生します。監視対象のJSPファイル数が増えると,オーバーヘッドも大きくなります。この場合は,更新検知間隔を長くすることで,性能への影響を少なくできます。
- includeディレクティブを使用してインクルードされたJSPファイルを更新しても,インクルード元のJSPファイルは再コンパイルされません。再コンパイルを実行する場合には,インクルード元のJSPファイルを更新してください。
All Rights Reserved. Copyright (C) 2006, 2007, Hitachi, Ltd.