クライアントからEnterprise JavaBeanに対して同時に要求が発行された場合、EJBコンテナは要求を別スレッドで実行して並列処理します。
スレッドの作成処理はレスポンス時間に影響するため、スレッドプールを活用してスレッドを再利用しています。
スレッドプーリングは以下のチューニングを行うことができます。
EJBアプリケーションの同時処理数制御
リクエストの優先順位付け
スレッドはEnterprise JavaBeanのアクセスパターンにより、制御が異なります。以下にEnterprise JavaBeanのアクセスパターンとスレッド制御の関係を説明します。
Enterprise JavaBeanのアクセスパターンとスレッド制御の関係
以下にEnterprise JavaBeanのアクセスパターンを示します。
以下の場合は、EJBコンテナがスレッドプールを使用してスレッド制御します。
RMI-IIOPによるリモートアクセスによりEnterprise JavaBeanに対して要求が発行される場合
JMSメッセージが受信され、Message-driven Beanが実行される場合
リソースアダプタのメッセージが受信され、Message-driven Beanが実行される場合
Session Beanの非同期メソッドが実行される場合
※「Session Beanの非同期処理スレッドのスレッドプール」を参照してください。
以下のJava VM内の呼出しの場合は、呼出し元のスレッドで動作します。
EJB間の呼出し
Servlet/JSPからのEJB呼出し
WebサービスからのEJB呼出し
JPA Entityに対する操作
HTTP通信によるアクセスの場合はスレッドのチューニングについては、「6.4 Webコンテナのチューニング」と「6.7 Webサービスのチューニング」を参照してください。
リソースアダプタのメッセージを受信するMessage-driven Beanの場合、メッセージリスナーメソッドはリソースアダプタが作成したスレッドで動作します。
EJBアプリケーションの同時処理数制御
IJServerクラスタプロセス起動時にスレッドプールの最小プールサイズのスレッドを作成しプールに格納します。
要求の処理開始前にプールを検索し、プールにスレッドがない場合、スレッドを作成して要求を実行します。
処理完了後、作成したスレッドは削除されることなくプールに返却されます。現在のスレッド数がスレッドプールの最大プールサイズとなり、プールにスレッドがない状態で要求が配信された場合、スレッドがプールに戻るまで要求をキューに入れて待機します。
リクエストの優先順位付け
RMI-IIOPによるリモートアクセスが行われるEJBアプリケーションでは、EJBアプリケーションごとにスレッドプールを作成し最大プール数を指定することにより、EJBアプリケーションごとに同時処理数を制御できます。
EJBアプリケーションに個別にスレッドプールを割り当てることによって、他のリモートアクセス対象のEJBアプリケーションよりも高い優先度で実行できます。個別のスレッドプールに割り当てられたEJBアプリケーションは、他のEJBアプリケーションに対する要求がスレッドプールでキューイングされていても独立したスレッドプールで実行できるため、優先的に実行できます。
スレッドプールの設定
以下にスレッドプールのチューニング項目について説明します。
チューニング項目 | 効果 |
---|---|
想定している同時に発行される要求数を指定するとレスポンスタイムを削減できます。 | |
スレッドプールの最大値によりスレッドプールが使用するメモリやリソースを制御できます。 | |
不要になった過度のスレッドを破棄することによりメモリやリソースの最適化ができます。 |
EJBアプリケーションでは、RMI-IIOPによるリモートアクセスにおいて、個別のスレッドプールが定義されている場合はそのスレッドプールが使用され、個別のスレッドプールが定義されていない場合は、用意されているデフォルトスレッドプールが使用されます。
デフォルトスレッドプールは、以下の機能でも使用されるため、EJBアプリケーションへの要求が多くなるとスレッドの空き待ちが発生し、遅延が発生する場合や応答がなくなる場合があります。
EJBタイマーサービスによるコールバックメソッドの実行
Enterprise Beanインスタンスのキャッシングによるpassivate処理の実行
Enterprise Beanインスタンスのプーリングによるプールの縮小や拡張処理の実行
スレッドプールIDを定義していないリソースアダプタのWorkの実行
別プロセスのEJBアプリケーションを呼び出した場合のリクエスト受信処理
RMI-IIOPによるリモートアクセスが行われるEJBアプリケーションについては、必ずデフォルトスレッドプールとは別のスレッドプールを作成し、「Enterprise Beanごとのスレッドプール設定」を行ってください。
各スレッドプールの利用イメージについては、「6.11.1 ORB」に記載されている通信データの流れを示した図を参照してください。
なお、デフォルトスレッドプールは、インストール直後の値が「thread-pool-1」になっています。このスレッドプールは削除しないでください。
Enterprise Beanごとのスレッドプールの最大プールサイズは、以下の見積もりを行ってください。
最大プールサイズ = 想定される最大クライアント多重度×2 (注1)
注1) 想定されるスレッド多重度の合計
デフォルトスレッドプール(thread-pool-1)の最大プールサイズは、以下の見積もりを行ってください。200より小さい値になった場合は、200(デフォルト)にしてください。
最大プールサイズ = EJBタイマーサービスのタイマーの数 + Enterprise Beanの数 + スレッドプールIDを定義していないリソースアダプタのWork数 + 想定される同時接続クライアントのプロセス数 + 想定される最大クライアント多重度 (注1) + 呼出し先IJServerクラスタのプロセス数 (注2)
注1) 想定されるスレッド多重度の合計。ただし、JMSメッセージが受信され、Message-driven Beanが実行される場合は、「想定される最大クライアント多重度×2」としてください。
注2) 他のIJServerクラスタのEJBアプリケーションなどを呼び出した場合の、呼出し先IJServerクラスタのプロセス数
注意
デフォルトスレッドプール(thread-pool-1)を使用する場合、スレッドを頻繁に切り替えるため、見積もった値より一時的に多くのスレッドを使用する場合があります。
スレッドプールは、asadminコマンドを使用して作成できます。詳細は、以下を参照してください。
スレッドプールの設定値は、asadminコマンドを使用して変更できます。詳細は、以下を参照してください。
作成したスレッドプールを、使用するEJBアプリケーションのInterstage deployment descriptorで指定します。詳細は、以下を参照してください。
「3.2.1.3 Interstage EJB application deployment descriptor (glassfish-ejb-jar.xml)」の<use-thread-pool-id>タグ
Session Beanのビジネスメソッドに@Asynchronousアノテーションを指定することで、そのメソッドを非同期で実行します。EJBコンテナごとにこの実行スレッドのスレッドプールを作成し最大プールサイズを指定することにより、同時処理数を制御できます。
非同期Session Beanのスレッドプールの設定については、以下のマニュアルを参照してください。