Application Server には、高いパフォーマンスとスケーラビリティーを備えた CORBA ORB (Object Request Broker) が含まれています。ORB は、サーバー上の EJB コンテナの基盤となります。
ORB は主に、次の経路で EJB コンポーネントによって使用されます。
アプリケーションクライアントコンテナを使用するアプリケーションクライアント (またはリッチクライアント) からの RMI/IIOP パス。
別の Application Server インスタンスの ORB からの RMI/IIOP パス。
別のベンダーの ORB からの RMI/IIOP パス。
Web コンテナまたは MDB (メッセージ駆動型 Beans) コンテナからのインプロセスパス。
あるサーバーインスタンスが別のサーバーインスタンスの ORB に接続する場合、その最初のインスタンスはクライアント ORB として機能します。SSL over IIOP では、暗号化アルゴリズムの高パフォーマンスなネイティブ実装を備えた、高速で最適化されたトランスポートが使用されます。
EJB のローカルインタフェースでは ORB が使用されない点に注意してください。ローカルインタフェースを使用する場合、引数はすべて参照として渡されるため、オブジェクトをコピーする必要はまったくありません。
あるリッチクライアント Java プログラムが新しい initialContext() 呼び出しを実行すると、クライアント側の ORB インスタンスが作成されます。次にこれが、Application Server IIOP ポートへのソケット接続を作成します。このクライアントからの IIOP 要求を処理するためのリーダースレッドが、サーバー ORB 上で起動されます。クライアントコードは initialContext を使って、サーバー上に配備された EJB の検索を行います。サーバー上に配備された EJB へのリモート参照である IOR が、クライアントに返されます。クライアントコードはこのオブジェクト参照を使って、EJB のリモートメソッドを呼び出します。
Bean の InitialContext 検索とメソッドの呼び出しでは、Java の整列化アプリケーション要求データが IIOP メッセージに変換され、そのメッセージが事前に作成されたソケット接続経由でサーバー ORB へと送信されます。するとサーバーは応答を作成し、それを同じ接続経由で送り返します。次に、応答内のそのデータがクライアント ORB によって非整列化され、クライアントコードに戻されて処理されます。リッチクライアントアプリケーションが終了すると、クライアント ORB は停止して接続を閉じます。
ORB 統計はデフォルトで無効になっています。ORB 統計を収集するには、次の asadmin コマンドを使って監視を有効にします。
set serverInstance.iiop-service.orb.system.monitoringEnabled=true reconfig serverInstance
ORB の接続に関して収集される統計は、次のとおりです。
total-inbound-connections ORB へのインバウンド接続の合計。
total-outbound-connections ORB からのアウトバウンド接続の合計。
ORB 接続の統計を取得するには、次のコマンドを使用します。
asadmin get --monitor serverInstance.iiop-service.orb.system.orb-connection.*
ORB のスレッドプールに関して収集される統計は、次のとおりです。
thread-pool-size ORB スレッドプール内のスレッドの数。
waiting-thread-count 作業の到着を待っているスレッドプールスレッドの数。
ORB スレッドプールの統計を取得するには、次のコマンドを使用します。
asadmin get --monitor serverInstance.iiop-service.orb.system.orb-thread-pool.*
ORB のパフォーマンスを調整するには、ORB のパラメータと ORB スレッドプールのパラメータを設定します。通常の場合、負荷分散、複数の共有接続、スレッドプール、およびメッセージ分割サイズを活用することで、応答時間を短縮できます。複数の ORB サーバー間でクライアント要求の負荷分散を行い、クライアントとサーバー間での接続数を調整することで、スケーラビリティーを改善できます。
次の表に、チューニング可能な ORB パラメータをまとめます。
表 3–5 チューニング可能な ORB 設定
パス |
ORB モジュール |
サーバー設定 |
アプリケーションクライアントからアプリケーションサーバーへの RMI/ IIOP |
通信インフラストラクチャー、スレッドプール |
steady-thread-pool-size、max-thread-pool-size、idle-thread-timeout-in-seconds |
ORB から Application Server への RMI/ IIOP |
通信インフラストラクチャー、スレッドプール |
steady-thread-pool-size、max-thread-pool-size、idle-thread-timeout-in-seconds |
ベンダー ORB からの RMI/ IIOP |
通信インフラストラクチャーの一部、スレッドプール |
steady-thread-pool-size、max-thread-pool-size、idle-thread-timeout-in-seconds |
インプロセス |
スレッドプール |
steady-thread-pool-size、max-thread-pool-size、idle-thread-timeout-in-seconds |
管理コンソールを使って次の ORB パラメータをチューニングします。
最大メッセージ分割サイズ: このバイト数よりも大きいメッセージは断片化されます。CORBA GIOPv1.2 の Request、Reply、LocateRequest、および LocateReply メッセージは、複数のフラグメントに分割できます。最初のメッセージは、flags フィールド内でより多くのフラグメントビットが true に設定された、通常の Request または Reply メッセージになります。ORB 間のメッセージの大部分がデフォルトサイズ (1024 バイト) よりも大きい場合、フラグメントのサイズを増やしてネットワーク上の待ち時間を短縮してください。
総接続数: 任意のタイミングにおけるすべてのリスナー上の受信接続の最大数。有限の数の接続を許可することで、サーバーの状態を保護します。この値は、接続からアクティブに読み取るスレッドの最大数に等しくなります。
ORB スレッドプールには、1 つのタスクキューと一連のスレッドが含まれます。タスクまたはジョブはこのタスクキューに挿入されますが、空き状態のスレッドがこのキューからタスクを取り出し、処理を実行します。タスクキューが常に空になるようなスレッドプールサイズを設定しないでください。大規模アプリケーションの場合、最大プールサイズが現在のタスクキューのサイズの 10 倍になるのが普通です。
Application Server は ORB スレッドプールを次の目的で使用します。
すべての ORB 要求を実行する。
EJB のプールおよびキャッシュを削除する。
したがって、ORB が RMI/ IIOP 経由のリモート呼び出し用として使用されない場合でも、EJB のプールおよびキャッシュのクリーンアップが円滑に進むように、このスレッドプールのサイズを設定してください。
ORB スレッドプールの属性を設定するには、「設定」>「config-name」>「スレッドプール」>「thread-pool-ID」を選択します。ここで、thread-pool-ID は ORB 用に選択されたスレッドプールの ID です。スレッドプールでパフォーマンスに影響を与える属性は、次のとおりです。
最小プールサイズ: ORB スレッドプール内のスレッドの最小数。通常 (RMI/ IIOP) 負荷時に必要となる平均スレッド数に設定します。
最大プールサイズ: ORB スレッドプール内のスレッドの最大数。
アイドルタイムアウト: アイドルスレッドをプールから削除するまでの待機秒数。スレッドプールの収縮を可能にします。
作業キューの数
特に、最大プールサイズがパフォーマンス上、重要になります。詳細については、「スレッドプールのサイジング」を参照してください。
クライアントプログラムを起動するときに、次のプロパティーをコマンド行引数として指定します。そうするには、Java VM の起動時に次の構文を使用します。
-Dproperty=value
クライアントでデフォルトの JDK ORB を使用する場合、クライアント ORB からアプリケーションサーバー ORB への接続が、初期コンテキストが作成されるたびに確立されます。同じプロセスからオープンされる接続のプーリングまたは共有を行うには、クライアント ORB の設定に次のコードを追加します。
-Djava.naming.factory.initial=com.sun.appserv.naming.S1ASCtxFactory
Sun Java System Application Server version 8.x では、プロパティー com.sun.appserv.iiop.orbconnections はサポートされていません。
コンテキストファクトリ (com.sun.appserv.naming.S1ASCtxFactory) を使用する場合、プロパティー com.sun.appserv.iiop.orbconnections を使用することで、クライアント ORB からサーバーに対してオープンする接続の数を指定できます。
デフォルト値は 1 です。複数の接続を使用すると、ネットワーク集約型アプリケーションのスループットが改善される可能性があります。クライアント ORB 上でこの設定変更を指定するには、次の jvm オプションを追加します。
-Djava.naming.factory.initial=com.sun.appserv.naming.S1ASCtxFactory -Dcom.sun.appserv.iiop.orbconnections=value
クラスタ内の複数のアプリケーションサーバーインスタンス向けに RMI/IIOP を設定する方法については、『Sun Java System Application Server Enterprise Edition 8.2 高可用性 (HA) 管理ガイド』の第 11 章「RMI-IIOP 負荷分散とフェイルオーバー」を参照してください。
クライアント ORB の負荷分散や接続数を調整する場合、サーバー ORB 上でオープンされる接続の数を考慮してください。小さい接続数から始め、その数を増やしながら何らかのパフォーマンス改善が見られるか監視します。サーバーへの 1 つの接続は、その接続からアクティブに読み取る 1 つの ORB スレッドへと変換されます (これらのスレッドはプールには格納されず、接続の存続期間中に一時的に存在する)。
前述したようにインバウンド接続とアウトバウンド接続の数を確認したあと、スレッドプールのサイズのチューニングを適切に行います。これは、パフォーマンスと応答時間に大きな影響を及ぼす可能性があります。
サイズを計算する際には、同時に処理するクライアント要求の数、マシン上で利用可能なリソース (CPU 数やメモリー容量)、およびクライアント要求処理時に必要とされる応答時間を考慮します。
このサイズを非常に小さい値に設定すると、サーバーが要求を同時に処理する能力に悪影響が及び、その結果として要求がタスクキュー内にとどまる時間が長くなるため、応答時間にも悪影響が及ぶ可能性があります。これに対し、多数のワークスレッドを使って要求を処理させるのも、問題が生じる可能性があります。なぜなら、システムリソースが大量に消費され、並行性が増大するからです。これは、スレッドが EJB コンテナ内の共有構造を取得するまでの時間が長くなることを意味する可能性があり、その結果、応答時間にも悪影響が及ぶ可能性があります。
また、ワークスレッドプールは、プールやキャッシュの削除など、EJB コンテナの整理アクティビティー用としても使用されます。サイズを決定する際には、このアクティビティーのことも考慮する必要があります。ORB ワークスレッドが多すぎるとパフォーマンスに悪影響が及ぶのは、サーバーがそれらすべてのスレッドを維持する必要が生じるからです。アイドルスレッドタイムアウト期間が過ぎると、アイドルスレッドは破棄されます。
Application Server によって渡された IIOP メッセージを調査することが役立つ場合があります。サーバーが IIOP メッセージを server.log ファイルに保存するようにするには、JVM オプション -Dcom.sun.CORBA.ORBDebug=giop を設定します。クライアント ORB 上で同じオプションを使用します。
サーバーログに保存される IIOP メッセージの例を、次に示します。注意: 実際の出力では、各行の先頭に [29/Aug/2002:22:41:43] INFO (27179): CORE3282: stdout のようなタイムスタンプが付きます。
++++++++++++++++++++++++++++++ Message(Thread[ORB Client-side Reader, conn to 192.18.80.118:1050,5,main]): createFromStream: type is 4 < MessageBase(Thread[ORB Client-side Reader, conn to 192.18.80.118:1050,5,main]): Message GIOP version: 1.2 MessageBase(Thread[ORB Client-side Reader, conn to 192.18.80.118:1050,5,main]): ORB Max GIOP Version: 1.2 Message(Thread[ORB Client-side Reader, conn to 192.18.80.118:1050,5,main]): createFromStream: message construction complete. com.sun.corba.ee.internal.iiop.MessageMediator (Thread[ORB Client-side Reader, conn to 192.18.80.118:1050,5,main]): Received message: ----- Input Buffer ----- Current index: 0 Total length : 340 47 49 4f 50 01 02 00 04 0 0 00 01 48 00 00 00 05 GIOP.......H....
フラグ -Dcom.sun.CORBA.ORBdebug=giop を指定すると、多数のデバッグメッセージがログ内に生成されます。これは、メッセージが断片化している疑いがある場合にのみ使用します。
このサンプル出力では、createFromStream のタイプが 4 と表示されています。これは、このメッセージがより大きなメッセージのフラグメントであることを意味しています。メッセージの断片化を防ぐには、フラグメントのサイズを増やします。フラグメントのサイズを大きくすると、メッセージがいくつかのフラグメントとしてではなく、1 つの単位として送信されるため、複数メッセージのオーバーヘッドが抑えられ、そうした複数のメッセージを受信側で結合する処理も必要なくなります。
アプリケーションで送信されるメッセージのほとんどが断片化されている場合、フラグメントサイズを増やせばおそらく効率が改善されます。これに対し、いくつかのメッセージだけが断片化されている場合、フラグメントサイズを小さくしたほうがメッセージの書き込みに必要とされるバッファーも小さくなり、より効率的である可能性があります。
ネットワーク上でのトランスポート用データで、標準の CDR (Common Data Representation) の代わりに Java 直列化を使用すると、ORB のパフォーマンスを改善できます。この機能は、Java Serialization over GIOP (General Inter-ORB Protocol) または JSG と呼ばれます。
場合によっては、JSG は CDR よりもパフォーマンスやスループットが良くなる可能性があります。そのパフォーマンスの差異は、アプリケーションによって大きく異なります。クライアントとサーバー間で少量のデータが転送されるようなリモートオブジェクトを含むアプリケーションで JSG を使用すれば、パフォーマンスが改善される可能性が非常に高くなります。
JSG を使用するすべてのサーバー上で、このプロパティーを設定する必要があります。
ツリーコンポーネントで、「設定」ノードを開きます。
目的のノードを展開します。
「JVM 設定」ノードを選択します。
「JVM 設定」ページで「JVM オプション」タブを選択します。
「JVM オプションを追加」をクリックし、次の値を入力します。
-Dcom.sun.CORBA.encoding.ORBEnableJavaSerialization=true
「保存」をクリックします。
Application Server を再起動します。
アプリケーションがスタンドアロンの非 Web クライアント (アプリケーションクライアント) を使用する場合、JSG を使用するには、クライアントアプリケーションのシステムプロパティーも設定する必要があります。これを行うには通常、クライアントアプリケーションの起動に使用される Java コマンド行に、このプロパティーを追加します。次に例を示します。
java -Dcom.sun.CORBA.encoding.ORBEnableJavaSerialization=true -Dorg.omg.CORBA.ORBInitialHost=gollum -Dorg.omg.CORBA.ORBInitialPort=35309 MyClientProgram