EJB コンテナには、パフォーマンスに影響を与える設定が数多くあります。EJB コンテナの実行やパフォーマンスを追跡するには、ほかの領域の場合と同じく、EJB コンテナの監視機能を使用します。
EJB コンテナの監視はデフォルトで無効になっています。管理コンソールで監視を有効にするには、「設定」>「config-name」>「監視」を選択します。すべての配備済み EJB コンポーネント、EJB プール、および EJB キャッシュを監視するには、「EJB コンテナ」の監視レベルを「低」に設定します。EJB ビジネスメソッドも監視するには、この監視レベルを「高」に設定します。
EJB コンテナは、EJB コンポーネントをキャッシュやプールに格納することでパフォーマンスの向上を図ります。キャッシュやプールのプロパティーを調整すれば、EJB コンテナのパフォーマンスを大幅に改善できます。EJB のキャッシュやプールの設定を行うには、管理コンソールの「設定」>「config-name」>「EJB コンテナ (EJB 設定)」を選択します。
プール設定がステートレスセッション Beans とエンティティー Beans で使用できるのに対し、キャッシュ設定はステートフルセッション Beans とエンティティー Beans で使用できます。
ステートレスセッション Beans とエンティティー Beans はどちらも、サーバーのパフォーマンスを改善する目的でプール内に格納できます。さらに、ステートフルセッション Beans とエンティティー Beans はどちらも、パフォーマンスを改善する目的でキャッシュ内に格納できます。
表 3–1 Bean タイプ別のプール処理またはキャッシュ処理
Bean 型 |
プール |
キャッシュ |
---|---|---|
ステートレスセッション |
可 |
不可 |
ステートフルセッション |
不可 |
可 |
エンティティー |
可 |
可 |
プール Bean とキャッシュ Bean の違いは、プール Beans はどれも等価であり、互いに区別できない、という点にあります。これに対し、キャッシュ Beans には、ステートフルセッション Beans の場合は対話状態が格納され、エンティティー Beans の場合は主キーが関連付けられます。エンティティー Beans は、ejbActivate() 呼び出し時にプールから削除されてキャッシュに追加され、ejbPassivate() 呼び出し時にキャッシュから削除されてプールに追加されます。ejbActivate() は、必要なエンティティー Bean がキャッシュ内に存在しない場合に、コンテナによって呼び出されます。ejbPassivate() は、キャッシュがその設定された上限を超えた場合に、コンテナによって呼び出されます。
Sun Java Studio を使って EJB コンポーネントを開発および配備する場合、個々の Bean 記述子の設定を、Bean プールや Bean キャッシュ向けに編集する必要があります。これらの設定は、本番レベルの配備に適していない可能性があります。
プール内の Bean は、EJB のライフサイクルにおけるプール状態を表します。つまり、その Bean は ID を持ちません。Bean をプール内に格納することの利点は、要求を処理するための Bean の作成時間を短縮できることにあります。このコンテナには、リクエストパスで Bean の作成時間を短縮できるよう、プールオブジェクトをバックグラウンドで作成するためのメカニズムが備わっています。
ステートレスセッション Beans とエンティティー Beans が EJB プールを使用します。ステートレスセッション Beans の使用方法やサーバーが処理するトラフィックの量に注意しながらプールサイズの調整を行い、Beans の過剰な作成や削除が発生しないようにしてください。
ある特定の EJB コンポーネントで、EJB コンテナのキャッシュ設定を上書きするキャッシュ設定を指定するには、その EJB コンポーネントの sun-ejb-jar.xml 配備記述子の <bean-pool> 要素を使用します。
EJB のプール設定は次のとおりです。
初期および最小プールサイズ: プール内に維持される Beans の初期および最小の数。有効な値は 0 から MAX_INTEGER までであり、デフォルト値は 8 です。EJB 配備記述子の対応する属性は、steady-pool-size です。
中程度の負荷がかかるシステムでは、このプロパティーをゼロよりも大きい数値に設定します。値をゼロよりも大きくすれば、受信要求を処理するインスタンスが、プール内に常に存在するようになります。
最大プールサイズ: クライアント要求に応えるために作成できる接続の最大数。有効な値はゼロから MAX_INTEGER までです。デフォルトは 32 です。値ゼロは、プールのサイズが無制限であることを意味します。これは、JVM ヒープがプール内のオブジェクトでいっぱいになる可能性があることを意味します。EJB 配備記述子の対応する属性は、max-pool-size です。
このプロパティーは、システムの予期される高負荷状態を表す値に設定してください。プールが大きすぎるとメモリーが無駄に消費され、システムのパフォーマンスが低下する可能性があります。プールが小さすぎても、多数の競合が発生するので非効率です。
プールサイズ変更量: キャッシュがサーバーによって処理されているときに作成または削除される Beans の数。有効な値はゼロから MAX_INTEGER までであり、デフォルトは 16 です。EJB 配備記述子の対応する属性は、resize-quantity です。
最大プールサイズを変更した場合はプールサイズ変更量も必ず調整し直し、バランスを維持できるようにしてください。一般に、最大プールサイズを大きくした場合には、プールサイズ変更量も大きくすべきです。
プールアイドルタイムアウト: ステートレスセッション Bean、エンティティー Bean、またはメッセージ駆動型 Bean がプール内でアイドル状態でいられる時間の最大値。この時間を経過した Bean がステートレスセッション Bean、メッセージ駆動型 Bean のいずれかである場合、その Bean は破棄されます。これはサーバーに対するヒントです。デフォルト値は 600 秒です。EJB 配備記述子の対応する属性は、pool-idle-timeout-in-seconds です。
プール内に存在している Beans が最大プールサイズよりも多い場合、そのプールのサイズは縮小されて初期および最小プールサイズに戻りますが、その処理は、プールアイドルタイムアウトに指定された間隔で、プールサイズ変更量の単位で行われます。サイズ変更量が小さすぎ、かつアイドルタイムアウトが大きいと、プールが縮小されて通常サイズに戻るまでに、非常に長い時間がかかります。
キャッシュ内の Bean は、EJB のライフサイクルにおける実行可能状態を表します。これは、その Bean に ID (主キーやセッション ID など) が関連付けられていることを意味します。
キャッシュの外側に移動する Beans は、EJB のライフサイクルに従って非活性化するか破棄する必要があります。非活性化された Bean をキャッシュ内に戻すには、その Bean を活性化する必要があります。エンティティー Beans は一般に、データベース内に格納され、何らかの形式のクエリー言語セマンティクスを使ってデータの読み込みや格納を行います。セッション Beans は、非活性化時にディスクまたはデータベースに格納するために直列化する必要があるほか、活性化時にも同様に直列化復元を行う必要があります。
こうしたキャッシュ内の「実行可能」Beans を使用する着信要求はすべて、作成、ID 設定、および場合によっては活性化のオーバーヘッドを回避することができます。したがって、理論上は、できるだけ多くの Beans をキャッシュに書き込むのが良いことになります。ところが、キャッシュへの書き込みには次のような欠点があります。
すべての Beans によって消費されるメモリーが、仮想マシン内で利用可能なヒープに影響を与える。
キャッシュ内のオブジェクトやメモリーを増やすと、ガベージコレクションの実行時間が長くなり、その実行頻度もおそらく多くなる。
ヒープのチューニングをピーク負荷に基づいて注意深く行わないかぎり、アプリケーションサーバーのメモリーが不足する可能性がある。
アプリケーションによるステートフルセッション Beans やエンティティー Beans の使用方法やサーバーが処理するトラフィックの量に注意しながら EJB のキャッシュサイズおよびタイムアウト設定のチューニングを行い、活性化や非活性化の回数が最小限に抑えられるようにしてください。
ある特定の EJB コンポーネントで、EJB コンテナのキャッシュ設定を上書きするキャッシュ設定を指定するには、その EJB コンポーネントの sun-ejb-jar.xml 配備記述子の <bean-cache> 要素を使用します。
EJB のキャッシュ設定は次のとおりです。
キャッシュ内の Beans の最大数。この設定は 1 より大きくしてください。デフォルト値は 512 です。値ゼロはキャッシュが無制限であることを示しますが、これは、キャッシュのサイズが「キャッシュアイドルタイムアウト」と「キャッシュのサイズ変更量」によって制御されることを意味します。EJB 配備記述子の対応する属性は、max-cache-size です。
キャッシュがサーバーによって処理されているときに作成または削除される Beans の数。有効な値はゼロから MAX_INTEGER までであり、デフォルトは 16 です。EJB 配備記述子の対応する属性は、resize-quantity です。
ステートフルセッション Bean が非活性化状態 (バックアップストア内でのアイドル状態) でいられる時間。ある Bean へのアクセスがこの期間が過ぎたあとも発生しなかった場合、その Bean はバックアップストアから削除され、クライアントからアクセスできなくなります。デフォルトは 60 分です。EJB 配備記述子の対応する属性は、removal-timeout-in-seconds です。
キャッシュからオブジェクトを削除するのに使用されるアルゴリズム。EJB 配備記述子の対応する属性は、victim-selection-policy です。選択肢は次のとおりです。
NRU (最近使用されていない): これがデフォルトですが、これは実際には擬似乱数選択ポリシーです。
FIFO (ファーストインファーストアウト)
LRU (最近の使用頻度がもっとも低い)
ステートフルセッション Bean またはエンティティー Bean がキャッシュ内でアイドル状態でいられる時間の最大値。この時間が経過した Bean は、非活性化されてバックアップストア内に格納されます。デフォルト値は 600 秒です。EJB 配備記述子の対応する属性は、cache-idle-timeout-in-seconds です。
読み取り専用 Bean がデータソースから更新される頻度。ゼロ (0) は、Bean が決して更新されないことを意味します。デフォルトは 600 秒です。EJB 配備記述子の対応する属性は、refresh-period-in-seconds です。注意: この設定に対応するカスタムフィールドは、管理コンソール内に存在しません。これを設定するには、「追加プロパティー」セクションの「プロパティーを追加」ボタンを使用してください。
sun-ejb-jar.xml 配備記述子に含まれる個々の EJB のプールおよびキャッシュ設定は、EJB コンテナの設定よりも優先されます。次の表は、キャッシュおよびプール設定の一覧を、EJB コンポーネントのタイプ別に示したものです。
表 3–2 EJB のキャッシュおよびプール設定
|
キャッシュ設定 |
プール設定 |
||||||||
---|---|---|---|---|---|---|---|---|---|---|
Bean のタイプ |
cache-resize-quantity |
max- cache-size |
cache-idle-timeout-in-seconds |
removal- timeout- in- seconds |
victim-selection- policy |
refresh-period-in-seconds |
steady-pool-size |
pool-resize-quantity |
max-pool-size |
pool-idle-timeout-in- seconds |
ステートフルセッション |
X |
X |
X |
X |
X | |||||
ステートレスセッション |
X |
X |
X |
X |
||||||
エンティティー |
X |
X |
X |
X |
X |
X |
X |
X |
X |
|
エンティティー (読み取り専用) |
X |
X |
X |
X |
X |
X |
X |
X |
X |
X |
メッセージ駆動型 Bean |
X |
X |
X |
コミットオプションは、ある EJB コンポーネントがトランザクションを完了したときに EJB コンテナによって実行されるアクションを制御します。コミットオプションはパフォーマンスに大きな影響を及ぼします。
コミットオプションで使用可能な値には次の 2 つがあります。
コミットオプション B:トランザクション完了時に、Bean はキャッシュ内に保存され、その ID を維持します。同じ主キーに対する次の呼び出しは、このキャッシュ内のインスタンスを使用できます。EJB コンテナは、データベースとの同期メソッドを呼び出す前に、Bean の ejbLoad() メソッドを呼び出します。
コミットオプション C:トランザクション完了時に、EJB コンテナは Bean の ejbPassivate() メソッドを呼び出します。Bean はその主キーとの関連付けを解除され、未使用プールへと戻されます。同じ主キーに対する次の呼び出しは、プールから未使用 Bean を取得し、そのインスタンスに PrimaryKey を設定したあと、そのインスタンス上で ejbActivate() を呼び出します。この場合も、EJB コンテナは、データベースとの同期メソッドを呼び出す前に、Bean の ejbLoad() メソッドを呼び出します。
オプション B では、ejbAcivate() と ejbPassivate() の呼び出しを避けられます。このため、ほとんどの場合、オプション C の場合よりもパフォーマンスが良くなります。なぜなら、プールからオブジェクトを取得したりオブジェクトを解放してプールに戻したりするオーバーヘッドの一部を回避できるからです。
ただし、オプション C のほうがパフォーマンスが良くなる場合もあります。キャッシュ内の Beans がほとんど再利用されず、Beans が継続的にキャッシュに追加されるようであれば、Beans をキャッシュに書き込む意味がありません。オプション C が使用される場合、コンテナは、メソッド呼び出し後やトランザクション完了時に、Beans をキャッシュに書き込む代わりにプールに戻します。このオプションでは、インスタンスの再利用がより効率的に行われるほか、JVM 内のライブオブジェクトの数が減少するのでガベージコレクションの高速化も図れます。
コミットオプション B、コミットオプション C のどちらを使用すべきかを決定するには、まず、Bean の監視コマンドを使ってキャッシュヒット数を調べます。キャッシュヒット数がキャッシュミス数を大幅に上回っている場合は、オプション B が適切な選択肢となります。最良の結果を得るためには、さらに max-cache-size と cache-resize-quantity を変更する必要がある可能性もあります。
キャッシュヒット数が極めて低く、かつキャッシュミス数が非常に多い場合、アプリケーションが Bean インスタンスを再利用できていないので、max-cache-size を使ってキャッシュサイズを増やしても効果はありません (アクセスパターンが同じままであると仮定した場合)。この場合はコミットオプション C を使用することができます。キャッシュヒット数とキャッシュミス数にあまり大きな違いがない場合には、max-cache-size をチューニングし、場合によっては cache-idle-timeout-in-seconds もチューニングしてください。