3.16.2 リソースアダプタのワーク管理
Connector 1.5仕様に準拠したリソースアダプタを使用する場合,リソースアダプタが使用するスレッドをJ2EEサーバによって管理できます。
リソースアダプタのワーク管理とは,リソースアダプタがマルチスレッドで動作する場合に,スレッドを適切に使用するための機能です。J2EEサーバは,スレッドをプールに管理しておき,必要なリソースアダプタに割り当てます。
- 注意事項
-
ワーク管理の対象になるWorkを実行するスレッドは,J2EEアプリケーションの実行時間監視の対象にはなりません。
J2EEアプリケーションの実行時間監視については,マニュアル「アプリケーションサーバ 機能解説 運用/監視/連携編」の「5.3 J2EEアプリケーションの実行時間の監視とキャンセル」を参照してください。
- 〈この項の構成〉
(1) 前提条件
リソースアダプタのワーク管理機能は,リソースアダプタのライフサイクルが管理されている場合に使用できます。リソースアダプタのライフサイクル管理については,「3.16.1 リソースアダプタのライフサイクル管理」を参照してください。
(2) ワーク管理に使用するクラス
リソースアダプタのワークを管理する場合に使用するクラスについて説明します。使用するクラスには,リソースアダプタでの実装が必要なクラスと,J2EEサーバが提供するクラスがあります。なお,J2EEサーバが提供するクラスは,ライフサイクル管理で使用するクラスと同じです。「3.16.1(2) ライフサイクル管理に使用するクラス」を参照してください。
(a) リソースアダプタで実装が必要なクラス
リソースアダプタでは,次のクラスの実装が必要です。
-
javax.resource.spi.work.Workインタフェースの実装クラス
このクラスのrunメソッドには,実行する処理を実装しておく必要があります。
なお,ワークの登録,ワークのスレッドへの割り当て,およびワークの終了のタイミングをリソースアダプタで管理したい場合は,javax.resource.spi.work.WorkListenerインタフェースの実装クラスも実装してください。
(3) ワーク管理の流れ
ここでは,ワーク管理の処理の流れについて説明します。
ワーク管理の概要を次の図に示します。
図で示した流れについて説明します。
-
Workの登録
リソースアダプタは,Work(javax.resource.spi.work.Workインタフェースの実装クラス)を生成して,WorkManagerに登録します。
このとき,WorkManagerのインスタンスは,BootstrapContext経由でリソースアダプタに渡されます。WorkManagerについては,「3.16.1 リソースアダプタのライフサイクル管理」を参照してください。
また,Workの登録と同時に,WorkManagerにWorkListener(javax.resource.spi.work.WorkListener)も登録すると,以降,Workの登録が完了したとき(1.が実行されたとき),Workにスレッドが割り当てられたとき(2.が実行されたとき),およびWorkの処理が完了したとき(3.が実行されたとき)に,それぞれイベント(javax.resource.spi.work.WorkEventインタフェースの実装クラス)を取得できます。
-
空きスレッドへのワークの割り当て
J2EEサーバは,WorkManagerに登録されたWorkに対して,空きスレッドを割り当てて,Workで実装されているrunメソッドを実行します。
-
Workの終了とスレッドの回収
J2EEサーバは,処理が完了したWorkに割り当てたスレッドを,スレッドプールに回収します。
回収されたスレッドは,スレッドプーリングでの設定に従って,プールに戻って待機状態になるか,解放されます。
なお,この流れの中で,javax.resource.spi.work.Workインタフェースまたはjavax.resource.spi.work.WorkListenerインタフェースのメソッドで例外が発生した場合は,それぞれKDJE48592-EまたはKDJE48593-Eのメッセージが出力されます。
WorkManagerに登録されたWorkの状態遷移を,次の図に示します。
なお,WorkManagerにWorkを登録する時に使用するメソッドによって,メソッドがリターンするタイミングが異なります。それぞれのメソッドがリターンするタイミングを次の表および図に示します。なお,リターンするタイミング以外,これらのメソッドの処理に違いはありません。
メソッド |
リターンするタイミング |
---|---|
scheduleWork |
Workを登録して,すぐにリターンします。 |
startWork |
Workにスレッドが割り当てられたタイミングでリターンします。 |
doWork |
Workの処理が完了したタイミングでリターンします。 |
(4) スレッドプーリング
スレッドプーリングは,ワークに割り当てるスレッドを,スレッドプールで管理する機能です。
(a) スレッドプーリングの設定
スレッドプーリングの設定は,リソースアダプタをJ2EEサーバにインポートしたあとで,Connector属性ファイルの<hitachi-connector-property>-<resourceadapter-runtime>-<property>タグに指定して,リソースアダプタごとのプロパティとして設定します。設定手順については,マニュアル「アプリケーションサーバ アプリケーション設定操作ガイド」の「5.4 リソースアダプタのプロパティ定義」を参照してください。
スレッドプールに設定できる値を次の表に示します。
設定できる値(プロパティ名) |
説明 |
---|---|
同時に実行される最大のスレッド数(MaxTPoolSize) |
WorkManagerで同時に実行される最大のスレッド数を設定します。 Workが登録されたときに空きスレッドがない場合,WorkManagerで実行中のスレッドの数がこの値未満であれば,新規にスレッドが生成されて,Workに割り当てられます。 実行中のスレッドの数がこの値以上のときには,Workの受け付けは拒否されて,javax.resource.spi.work.WorkRejectedExceptionがスローされます。 |
スレッドプールの最小スレッド数(MinTPoolSize) |
スレッドプールにプールする最小スレッド数を設定します。 WorkManagerにWorkがまったく登録されていない場合でも,この値分のスレッドは常にプールされます。 また,この値に0を指定した場合は,Workが登録されるまで,スレッドは生成されません。 |
Workが割り当たっていないスレッドが解放されるまでの最大生存期間[単位:秒](TPoolKeepalive) |
Workが割り当てられていないスレッドが,スレッドプールから解放されるまでの期間を秒単位で設定します。 空きスレッドになってからTPoolKeepalive秒経過してもWorkが割り当てられなかった場合,そのスレッドは解放されます。 ただし,スレッドプールに存在するスレッド数がMinTPoolSizeの値分しかない場合は,解放されません。 |
指定方法および指定できる値の詳細については,マニュアル「アプリケーションサーバ リファレンス 定義編(アプリケーション/リソース定義)」の「4.1 Connector属性ファイル」を参照してください。
なお,ライフサイクル管理機能が有効でない場合(リソースアダプタのDD(ra.xml)に<resourceadapter-class>が指定されていない場合),スレッドプーリングを設定するプロパティの値は無視されます。
(b) ワーク管理で使用するスレッドのライフサイクル
ワーク管理機能で使用するスレッドのライフサイクルを次に図に示します。
スレッドのライフサイクルは,スレッドプールと実行中スレッドの状態によって異なります。
スレッドが生成されるのは,リソースアダプタによってscheduleWorkメソッド,startWorkメソッドまたはdoWorkメソッドが呼び出された場合に,次の状態の両方に当てはまるときです。
-
スレッドプールに空きスレッドがない。
-
WorkManagerで実行中のスレッド数がMaxTPoolSize未満である。
スレッドは,Workの処理が完了するとスレッドプールで実行待ち状態になります。次のWorkが登録されると,再度実行状態になります。
スレッドプール内で,TPoolKeepaliveで指定した秒数が経過してもWorkが割り当てられなかった場合,スレッドは解放されます。ただし,そのスレッドを解放することでスレッドプール内のスレッド数がMinTPoolSize未満になる場合は,解放されません。
(c) Message-driven Beanのインスタンスプールとスレッドプーリングとの関係
リソースアダプタがWorkを使用してMessage-driven Beanを呼び出す場合の動作は,Message-driven Beanのインスタンスプールの最大数と,リソースアダプタのMaxTPoolSizeの関係によって異なります。
Message-driven Beanのインスタンスプールの最大数とリソースアダプタのMaxTPoolSizeの関係ごとの動作を次の表に示します。これは,一つのリソースアダプタから一つのMessage-driven Beanを呼び出す場合の動作です。
Message-driven Beanのインスタンスプールの最大数とリソースアダプタのMaxTPoolSizeの関係 |
動作 |
---|---|
MaxTPoolSize>Message-driven Beanのインスタンスプールの最大数 |
Message-driven Beanのインスタンスプールの最大数に達するまで,WorkからMessage-driven Beanを実行できます。 Message-driven Beanのインスタンスプールの最大数を超える数のWorkは,Message-driven Beanのインスタンスの取得待ちの状態になります。 |
MaxTPoolSize=Message-driven Beanのインスタンスプールの最大数 |
Message-driven Beanのインスタンスプールの最大数に達するまで,WorkからMessage-driven Beanを実行できます。 Message-driven Beanのインスタンスプールの最大数を超える数のWorkに対しては,javax.resource.spi.work.WorkRejectedException例外がスローされます。インスタンスの取得待ちにはなりません。 |
MaxTPoolSize<Message-driven Beanのインスタンスプールの最大数 |
同時に使用できるMessage-driven Beanのインスタンス数は,MaxTPoolSizeの数になります。実行中のWorkの数がMaxTPoolSizeに達するまで,WorkからMessage-driven Beanを実行できます。 MaxTPoolSizeを超える数のWorkに対しては,javax.resource.spi.work.WorkRejectedException例外がスローされます。実行待ちにはなりません。 |
- ポイント
-
ワーク管理機能のスレッドプーリングはリソースアダプタ単位に設定します。一方,Message-driven BeanのインスタンスプールはMessage-driven Bean単位に設定します。
リソースアダプタが複数のMessage-driven Beanを呼び出す場合,リソースアダプタのMaxTPoolSizeには,それぞれのMessage-driven Beanで必要なスレッド数を考慮して,合計した値を設定してください。
(5) ワーク管理の開始処理と終了処理
ワーク管理の開始処理および終了処理は,ライフサイクル管理機能の開始処理および終了処理のタイミングで実行されます。
それぞれの処理で実行されることを次に示します。
(a) 開始処理
ワーク管理の開始処理では,スレッドプーリングの設定に応じて,スレッドの生成が実行されます。MinTPoolSizeが1以上に設定されている場合は,MinTPoolSize分のスレッドが生成されて,空きスレッドとしてスレッドプールに格納されます。
(b) 終了処理
終了処理で実行される内容は,正常終了の場合と,異常終了または強制終了の場合とで一部異なります。なお,異常終了とは,ResourceAdapterインタフェースのstopメソッド実行時に例外がスローされる場合のことです。また,強制終了とは,cjstopapp -forceコマンドまたはcjstopapp -cancelコマンド実行の延長で実行される終了処理のことです。
- 参考
-
cjstopsv -fコマンドを実行した場合は,リソースアダプタの終了処理が実行されないでJ2EEサーバが停止されます。このため,ここで説明する処理は実行されません。
-
J2EEサーバからResourceAdapterインタフェースのstopメソッドが呼び出され,リソースアダプタに対して,停止処理が指示されます。
また,この処理の延長でWorkのreleaseメソッドが呼び出されて,Workが解放されます。
-
リソースアダプタによって,新規のWorkの受け付けが停止されます。
1.の処理を実行したあとなので,通常,Workの登録要求はありません。Workの登録要求があった場合,例外として,javax.resource.spi.work.WorkRejectedExceptionがスローされます。
-
Workの処理完了が待機されます。
実行中のWorkのrunメソッドの実行がすべて完了するまで待機されます。
- ポイント
-
-
Workから呼び出しているMessage-driven Beanに対してメソッドキャンセルが実行されると,Message-driven Beanは強制終了します。ただし,その場合,実行中のWorkの処理は停止されません。
-
WorkからMessage-driven Beanを呼び出している場合,リソースアダプタよりも先にMessage-driven Beanが終了します。Message-driven Bean停止後にWorkからMessage-driven Beanを呼び出したり,javax.resource.spi.endpoint.MessageEndpointFactoryのcreateEndpointメソッドを呼び出したりすると,例外がスローされます。
詳細は,「3.16.3 メッセージインフロー」を参照してください。
-