この章では、Oracle Tuxedoシステムの主要なスケーラビリティ機能を利用してCORBAサーバー・アプリケーションのスケーラビリティを高める方法について、Production Universityサンプル・アプリケーションを例にして説明します。Productionサンプル・アプリケーションは、これらのスケーラビリティ機能を利用して以下の目標を達成します。
高度にスケーラブルなアプリケーションのサポートは、Oracle Tuxedoシステムの長所の1つです。多くのアプリケーションは、1 - 10のサーバー・プロセス、および10 - 100のクライアント・アプリケーションが動作している環境で良好に機能します。しかし、ビジネス環境では、アプリケーションは次のレベルの処理をサポートする必要があります。
このような要件を負ったアプリケーションをデプロイすると、リソースの不足およびパフォーマンスのボトルネックがすぐに表面化します。Oracle Tuxedoシステムではこうした大規模なデプロイメントが複数の方法でサポートされていて、この章ではそれらのうち次の3つについて説明します。
アプリケーションを高度にスケーラブルにするためにOracle Tuxedoシステムで提供されているほかの機能には、IIOPリスナー/ハンドラがあります。概要については『Oracle Tuxedo CORBAアプリケーション・スタート・ガイド』、詳細な説明については『Oracle Tuxedoアプリケーションの設定』を参照してください。また、『CORBAアプリケーションのスケーリング、分散およびチューニング』も参照してください。
ここでは、非常に大規模な処理機能を実現できるようにアプリケーションをスケーリングする方法について、Productionサンプル・アプリケーションを例にして説明します。Productionサンプル・アプリケーションの設計上の基本的な目標は、対応できるクライアント・アプリケーションの数を大幅に増やすために、次のように対処することです。
こうした設計目標に対応するために、Productionサンプル・アプリケーションでは次の処理をします。
注: | Productionサンプル・アプリケーションを使いやすくするために、このアプリケーションは1台のマシン上で1つのデータベースを使用して実行できるようにOracle Tuxedoソフトウェア・キット上で構成されています。ただし、この章で示した例では、アプリケーションは2つのデータベースを使って2つのマシン上で動作しています。 |
注: | Productionサンプル・アプリケーションの設計では、複数台のマシン上で複数のデータベースを使用して実行する構成が可能になるように設定されています。複数のマシンおよびデータベースを使用するように構成を変更する作業には、UBBCONFIG ファイルの変更とデータベースの分離が関係し、これらの詳細は「Productionサーバー・アプリケーションをさらにスケーリングする方法」で説明されています。 |
以後の各項では、Productionサンプル・アプリケーションのスケーラビリティの目標を達成するために、レプリケートされたサーバー・プロセスおよびサーバー・グループの使用、オブジェクト状態管理、およびファクトリ・ベース・ルーティングについて説明します。次の項では、Productionサンプル・アプリケーションに実装されているOMG IDLの変更について説明します。
Productionサンプル・アプリケーションでのOMG IDLの変更は、RegistrarFactory
オブジェクトのfind_registrar()
操作、およびTellerFactory
オブジェクトのfind_teller()
操作に限定されています。これら2つの操作はそれぞれ、ファクトリ・ベース・ルーティングの実装に必要な学生IDと口座番号を要求するように変更されます。Productionサンプル・アプリケーションでのファクトリ・ベース・ルーティングの実装および使用については、「ファクトリ・ベース・ルーティング」を参照してください。
Oracle Tuxedoシステムでは、サーバー・アプリケーションの構成に多様な選択肢が用意されています。たとえば、以下の構成が可能です。
次の項では、レプリケートされたサーバー・プロセスおよびグループについて説明するほか、それらをOracle Tuxedoシステムに構成する方法についても説明します。
使用するアプリケーションでサーバー・プロセスをレプリケートすると、以下の利点があります。
レプリケートされたサーバー・プロセスの利点を完全に活用するには、使用するサーバー・アプリケーションによってインスタンス化される各オブジェクトのすべてが一意のIDを持つようにしてください。こうすれば、オブジェクト上でのクライアント呼出しによって必要なオブジェクトがインスタンス化される処理が、利用可能な複数のサーバー・プロセスの境界内で実行されるので、すでにアクティブ化されているオブジェクトのためのキューに入れられずに済みます。
図8-1は、次のことを示します。
この図では、2つのグループは1台のマシンで実行されているものとして示されます。
これらのグループのいずれかにリクエストが着信したとき、Oracle Tuxedoドメインにはリクエストを処理できる利用可能なサーバー・プロセスが複数あり、Oracle Tuxedoドメインは最も負荷の少ないサーバー・プロセスを選択することができます。
図8-1では、次の点に注意してください。
サーバー・グループの概念はOracle Tuxedoシステムに固有のもので、CORBAの実装に追加されます。サーバー・グループは、Oracle Tuxedoシステムのスケーラビリティ機能の重要な要素です。基本的に、デプロイメント・システムにマシンを追加する場合は、グループを追加する必要があります。
図8-2は、別のマシンにレプリケートされたProductionサンプル・アプリケーションのグループを示します。このアプリケーションのUBBCONFIG
ファイルに指定されているとおり、ORA_GRP2とAPP_GRP2があります。
図8-2では、Productionマシン1と2のグループの内容で異なるのはデータベースのみです。Productionマシン1用のデータベースには、学生のサブセットについて、学生情報および口座情報が含まれています。Productionマシン2用のデータベースには、学生の別のサブセットについて、学生情報および口座情報が含まれています。(両方のデータベースにあるコース情報の表は同じ内容です。)データベースにある学生情報が、同じデータベース内の口座情報とは完全に無関連であることに注意してください。
サーバー・グループの構成の方法、実行場所、およびレプリケートの方法は、UBBCONFIG
ファイルに指定されています。サーバー・グループをレプリケートすると、次の処理が可能になります。
複数のサーバー・グループを持つと、次のような影響があります。
Productionサンプル・アプリケーションがファクトリ・ベース・ルーティングを使用して複数台のマシンにアプリケーションの処理負荷を分散させる方法の詳細は、「ファクトリ・ベース・ルーティング」を参照してください。
使用するOracle Tuxedoドメインにあるレプリケートされたサーバー・プロセスおよびグループを構成するには、以下の手順に従います。
UBBCONFIG
ファイルを、「ワードパッド」などのテキスト・エディタで開きます。GROUPS
セクションで、構成するグループの名前を指定します。SERVERS
セクションに、レプリケートするサーバー・プロセスに関する次の情報を入力します。GROUP
パラメータ。サーバー・プロセスが属するグループの名前を指定します。複数のグループに関係するサーバー・プロセスをレプリケートする場合は、各グループに1つずつサーバー・プロセスを指定します。SRVID
パラメータ。数値識別子を指定して、サーバー・プロセスに一意のIDを割り当てます。MIN
パラメータ。アプリケーションの起動時に開始されるサーバー・プロセスのインスタンスの数を指定します。MAX
パラメータ。同時に実行できるサーバー・プロセスの最大数を指定します。 MIN
およびMAX
パラメータは、指定されたオブジェクトへのリクエストをサーバー・アプリケーションでどの程度まで並行処理できるかを決定します。実行時には、必要に応じて、システム管理者がリソースのボトルネックを調べて、新しいサーバー・プロセスを起動することができます。このアプリケーションは、システム管理者がスケーリングできるように設計されています。
次に、Productionサンプル・アプリケーションのUBBCONFIG
ファイルのGROUPS
およびSERVERS
セクションから引用した行を例示します。
*GROUPS
APP_GRP1
LMID = SITE1
GRPNO = 2
TMSNAME = TMS
APP_GRP2
LMID = SITE1
GRPNO = 3
TMSNAME = TMS
ORA_GRP1
LMID = SITE1
GRPNO = 4
OPENINFO = "BEA_XA:BEA_XA+Acc=P/scott/..."
CLOSEINFO = ""
TMSNAME = "TMS_ORA"
ORA_GRP2
LMID = SITE1
GRPNO = 5
OPENINFO = "BEA_XA:BEA_XA+Acc=P/scott/..."
CLOSEINFO = ""
TMSNAME = "TMS_ORA"
*SERVERS
# By default, activate 2 instances of each server
# and allow the administrator to activate up to 5
# instances of each server
DEFAULT:
MIN = 2
MAX = 5
tellp_server
SRVGRP = ORA_GRP1
SRVID = 10
RESTART = N
tellp_server
SRVGRP = ORA_GRP2
SRVID = 10
RESTART = N
billp_server
SRVGRP = APP_GRP1
SRVID = 10
RESTART = N
billp_server
SRVGRP = APP_GRP2
SRVID = 10
RESTART = N
univp_server
SRVGRP = ORA_GRP1
SRVID = 20
RESTART = N
univp_server
SRVGRP = ORA_GRP2
SRVID = 20
RESTART = N
「CORBAサーバー・アプリケーションの概念」で説明したように、オブジェクト状態管理は大規模なクライアント/サーバー・システムでは根本的に重要な検討事項です。それは、こうしたシステムでは最適なスループットおよび応答時間を実現することが重要であるためです。この節では、Oracle Tuxedoサーバー・アプリケーションによって管理されるオブジェクトのスケーラビリティを高めるためにオブジェクト状態管理を使用する方法を、Productionサンプル・アプリケーションのRegistrar
およびTeller
オブジェクトを例にして説明します。
次の表は、使用するOracle Tuxedoアプリケーションのスケーラビリティを大きく高めるために、Oracle Tuxedoシステムでサポートされているオブジェクト状態管理モデルを使用する方法をまとめたものです。
メソッド・バウンド・オブジェクトは、クライアントによって呼び出されている間だけ、マシンのメモリーへ格納されます。呼出しが完了すると、オブジェクトは非アクティブ化され、そのオブジェクトの状態データはすべて、メモリーからフラッシュされます。
|
|
スケーラビリティによるパフォーマンス向上を達成するには、Productionサーバー・アプリケーションのRegistrar
およびTeller
オブジェクトを、method
アクティブ化ポリシーを持つように構成する必要があります。これら2つのオブジェクトにmethod
アクティブ化ポリシーを割り当てた結果、振る舞いに次の変化がみられます。
Basicサンプル・アプリケーションからWrapperサンプル・アプリケーションを通じて、Registrar
オブジェクトはプロセス・バウンドです。このオブジェクトへのすべてのクライアント・リクエストは、マシンのメモリーにある同じオブジェクトのインスタンスへ送られます。Basicサンプル・アプリケーションの設計は、すべての小規模なデプロイメントに適しています。しかし、クライアント・アプリケーションのリクエストが増すにつれて、Registrar
オブジェクト上のクライアント・リクエストはキューに入れられるようになり、このためレスポンス時間が遅くなります。
しかし、Registrar
およびTeller
オブジェクトがステートレスで、これらのオブジェクトを管理するサーバー・プロセスがレプリケートされていれば、これらのオブジェクトはクライアント・リクエストの並行処理に利用可能になります。これらのオブジェクトで同時に処理できるクライアント・リクエストの数に対する唯一の制限は、これらのオブジェクトをインスタンス化できる利用可能なサーバー・プロセスの数です。したがって、これらのステートレス・オブジェクトはマシン・リソースのより効率的な使用と、クライアントレスポンス時間の短縮を実現します。
最も重要なのは、Oracle TuxedoシステムがRegistrar
およびTeller
オブジェクトのコピーを、両オブジェクトごとにレプリケートされたサーバー・プロセス内でインスタンス化できるようにするためには、これらのオブジェクトのコピーが一意である必要があるということです。これらのオブジェクトの各インスタンスを一意にするために、オブジェクトのファクトリでは一意のオブジェクトIDをオブジェクトに割り当てる必要があります。このことも含めて、これら2つのオブジェクトに関する設計上の検討事項については、「RegistrarおよびTellerオブジェクトに関する設計上の追加考慮事項」を参照してください。
ファクトリ・ベース・ルーティングは、特定のサーバー・グループへクライアント・リクエストを送信する方法を提供する強力な機能です。ファクトリ・ベース・ルーティングを使用すれば、アプリケーションの処理負荷を複数のマシンに分散できます。これは、指定されたオブジェクトがインスタンス化されるグループ、つまりマシンを決定できるからです。
ファクトリ・ベース・ルーティングを使用すれば、Oracle Tuxedoシステムの様々なロード・バランシング機能およびスケーラビリティ機能を拡張することができます。Productionサンプル・アプリケーションの場合、ファクトリ・ベース・ルーティングを使用すれば、学生のサブセットの1つを登録するリクエストを1台のマシンへ送信し、別のサブセットに関するリクエストは別のマシンへ送信することができます。使用するアプリケーションの処理能力を増やすためにマシンを追加しても、Oracle Tuxedoシステムではアプリケーションのファクトリ・ベース・ルーティングを簡単に変更してマシンの追加に対応できます。
ファクトリ・ベース・ルーティングの第一の利点は、デプロイメント環境の拡大に対応して、アプリケーション、特にインタフェースの呼出し機能をスケール・アップするための簡単な方法が提供されることです。アプリケーションのデプロイメント範囲を追加マシンにも広げることは、厳密には管理用の機能であり、アプリケーションの再コーディングや再ビルドは不要です。
クライアント/サーバー・アプリケーションにファクトリ・ベース・ルーティングを実装する際に設計上最も重要な検討事項は、ルーティングのベースとなる値の選択です。以下の節では、ファクトリ・ベース・ルーティングの機能について、Productionサンプル・アプリケーションを使用して説明します。Productionサンプル・アプリケーションは、ファクトリ・ベース・ルーティングを次のように使用します。
ファクトリでファクトリ・ベース・ルーティングを実装する際には、ファクトリがオブジェクト参照を作成する方法が変更されます。すべてのオブジェクト参照はグループIDを含み、デフォルトのグループIDはオブジェクト参照を作成するファクトリと同じになります。しかし、ファクトリ・ベース・ルーティングを使用する場合、ファクトリはグループIDを決定するルーティング基準も含めてオブジェクト参照を作成します。その後、クライアント・アプリケーションがこうしたオブジェクト参照を使用して呼出しを送信すると、Oracle Tuxedoシステムによって、リクエストはオブジェクト参照に指定されたグループIDへルーティングされます。ここでは、オブジェクト参照に関するグループIDがどのようにして生成されるかを説明します。
ファクトリ・ベース・ルーティングを実装するには、次の項目を調整する必要があります。
調整が必要なデータについて説明するために、以降の2つの項では、UBBCONFIG
ファイルでのファクトリ・ベース・ルーティングの構成と、ファクトリでのファクトリ・ベース・ルーティングの実装を説明します。
リクエストがルーティングされる各インタフェースについて、UBBCONFIG
ファイルに次の情報を記述する必要があります。
ファクトリ・ベース・ルーティングを構成するには、UBBCONFIG
ファイルのINTERFACES
およびROUTING
セクションで次のデータを指定するほか、グループおよびマシンを識別する方法を指定する必要があります。
INTERFACES
セクションには、ファクトリ・ベース・ルーティングを有効にするインタフェースの名前の一覧が示されます。各インタフェースについて、このセクションでインタフェースのルーティングの基準の種類を指定します。このセクションでは、次の例のように、FACTORYROUTING
という識別子でルーティング基準を指定します。INTERFACES
"IDL:beasys.com/UniversityP/Registrar:1.0"
FACTORYROUTING = STU_ID
"IDL:beasys.com/BillingP/Teller:1.0"
FACTORYROUTING = ACT_NUM
上の例では、Productionサンプルでファクトリ・ベース・ルーティングが使用される2つのインタフェースの完全修飾されたインタフェース名を示します。FACTORYROUTING
識別子は、ルーティング値の名前を指定します。値はそれぞれ、STU_ID
およびACT_NUM
です。
ROUTING
セクションでは、ルーティング値ごとに以下のデータを指定します。TYPE
パラメータでは、ルーティングのタイプを指定します。Productionサンプルでは、ルーティングのタイプはファクトリ・ベース・ルーティングです。したがって、このパラメータは、FACTORY
と定義します。FIELD
パラメータは、ファクトリがルーティング値に挿入する名前を指定します。Productionサンプルでは、フィールド・パラメータはそれぞれ、student_id
およびaccount_number
です。FIELDTYPE
パラメータは、ルーティング値のデータ型を指定します。Productionサンプルでは、student_id
およびaccount_number
のフィールド型はlong
です。RANGES
パラメータ。各グループにルーティングされる値を指定します。 次に、Productionサンプル・アプリケーションで使用するUBBCONFIG
ファイルのROUTING
セクションの例を示します。
ROUTING
STU_ID
FIELD = "student_id"
TYPE = FACTORY
FIELDTYPE = LONG
RANGES = "100001-100005:ORA_GRP1,100006-100010:ORA_GRP2"
ACT_NUM
FIELD = "account_number"
TYPE = FACTORY
FIELDTYPE = LONG
RANGES = "200010-200014:APP_GRP1,200015-200019:APP_GRP2"
上の例では、一方の範囲に入るIDを持った学生についてのRegistrar
オブジェクト参照は一方のサーバー・グループにルーティングされ、もう一方の範囲に入るIDを持った学生についてのRegistrar
オブジェクト参照は他方のグループにルーティングされるということが示されています。同様に、ある1つの範囲の口座に対するTeller
オブジェクト参照は、ある1つのサーバー・グループにルーティングされ、別の範囲の口座に対するTeller
オブジェクト参照は、別のグループにルーティングされます。
UBBCONFIG
ファイルのROUTING
セクションにあるRANGES
識別子で指定されたグループを識別および構成する必要があります。たとえば、ProductionサンプルはAPP_GRP1、APP_GRP2、ORA_GRP1、およびORA_GRP2という4つのグループを指定します。これらのグループを構成し、グループが実行されるマシンを識別する必要があります。 次の例は、ProductionサンプルのUBBCONFIG
ファイルのGROUPS
セクションを示します。このセクションで、ORA_GRP1およびORA_GRP2グループが構成されています。GROUPS
セクションに列挙されている名前が、ROUTING
セクションに指定されているグループ名とどのように一致するかに注目してください。さらに、アプリケーションでグループを構成する方法に関する何らかの変更も、ROUTING
セクションに反映させる必要があります。(Oracle Tuxedoソフトウェアに収録されているProductionサンプルは、1台のマシンで実行するように構成されていることに注意してください。しかし、このアプリケーションを複数のマシンで実行するように構成することも容易にできます。)
*GROUPS
APP_GRP1
LMID = SITE1
GRPNO = 2
TMSNAME = TMS
APP_GRP2
LMID = SITE1
GRPNO = 3
TMSNAME = TMS
ORA_GRP1
LMID = SITE1
GRPNO = 4
OPENINFO = "BEA_XA:BEA_XA+Acc=P/scott/..."
CLOSEINFO = ""
TMSNAME = "TMS_ORA"
ORA_GRP2
LMID = SITE1
GRPNO = 5
OPENINFO = "BEA_XA:BEA_XA+Acc=P/scott/..."
CLOSEINFO = ""
TMSNAME = "TMS_ORA"
ファクトリは、TP::create_object_reference()
操作への呼出しが実装されている方法によってファクトリ・ベース・ルーティングを実装します。この操作には、次のC++バインドがあります。
CORBA::Object_ptr TP::create_object_reference (
const char* interfaceName,
const PortableServer::oid &stroid,
CORBA::NVlist_ptr criteria);
この操作に対する3番目のパラメータであるcriteria
は、ファクトリ・ベース・ルーティングに使用される、名前の付いた値を指定します。このため、ファクトリでファクトリ・ベース・ルーティングを実装する機能は、NVlist
をビルドすることにあります。
前述のように、Productionサンプル・アプリケーションのRegistrarFactory
オブジェクトは、値STU_ID
を指定します。この値は、UBBCONFIG
ファイルの次の項目と正確に一致する必要があります。
RegistrarFactory
オブジェクトは、次のコードを使用してNVlist
に学生IDを挿入します。
// put the student id (which is the routing criteria)
// into a CORBA NVList:
CORBA::NVList_var v_criteria;
TP::orb()->create_list(1, v_criteria.out());
CORBA::Any any;
any <<= (CORBA::Long)student;
v_criteria->add_value("student_id", any, 0);
RegistrarFactory
オブジェクトは次のようにしてTP::create_object_reference()
操作を呼び出し、前のサンプル・コードで作成されたNVlist
を渡します。
// create the registrar object reference using
// the routing criteria :
CORBA::Object_var v_reg_oref =
TP::create_object_reference(
UniversityP::_tc_Registrar->id(),
object_id,
v_criteria.in()
);
Productionサンプル・アプリケーションはまた、TellerFactory
オブジェクトでもファクトリ・ベース・ルーティングを使用し、口座番号に基づいてTeller
オブジェクトがインスタンス化されるべきグループを決定します。
注: | 指定されたインタフェースおよびOIDを持つ1つのオブジェクトが2つの異なるグループで同時にアクティブ化されることも、それら2つのグループに同じオブジェクト実装がある場合には起こりえます。(しかし、使用するファクトリで一意のOIDが生成されていれば、こうした状況はほぼありません。)指定されたインタフェース名およびOIDの1つのオブジェクト・インスタンスがドメイン内で一度に1つだけ利用可能であることを保証する必要がある場合は、次のいずれかを行います。つまり、ファクトリ・ベース・ルーティングを使用して、特定のOIDのオブジェクトが常に同じグループにルーティングされるようにするか、指定されるオブジェクト実装が1つのグループのみに存在するようにドメインを構成するかです。そうすれば、指定されたインタフェース名およびOIDを持つ1つのオブジェクトに複数のクライアントがオブジェクト参照をした場合でも、その参照は常に同じオブジェクト・インスタンスへルーティングされることになります。 |
注: | オブジェクトのOIDによるルーティングを利用可能にするには、TP::create_object_reference() 操作でOIDをルーティング基準に指定してから、UBBCONFIG ファイルをそれに合わせて設定します。 |
ファクトリでファクトリ・ベース・ルーティングを実装するとき、Oracle Tuxedoシステムによってオブジェクト参照が生成されます。次の例は、ファクトリ・ベース・ルーティングが実装されているときにクライアント・アプリケーションがRegistrar
オブジェクトへのオブジェクト参照を取得する方法を示します。
RegistrarFactory
オブジェクトを呼び出し、Registrar
オブジェクトの参照をリクエストします。リクエストには学生IDが含まれます。RegistrarFactory
は、NVlist
に学生IDを挿入します。これは、ルーティング基準として使用されます。RegistrarFactory
は、TP::create_object_reference()
操作を呼び出し、Registrar
インタフェース名、一意のOID、およびNVlist
を渡します。NVlist
の値と比較して、グループIDを判別します。続いてクライアント・アプリケーションがオブジェクト参照を使用してオブジェクト呼出しを実行した場合、Oracle Tuxedoシステムはそのリクエストを、オブジェクト参照で指定されたグループへルーティングします。
注: | Process-Entityデザイン・パターンを使用する場合は、ファクトリ・ベース・ルーティングの実装に注意してください。オブジェクトは、グループのデータベースに格納されているエンティティしか処理できません。 |
Registrar
およびTeller
オブジェクトの設計に影響する主な考慮事項には、以下のものがあります。
Registrar
およびTeller
オブジェクトがProductionのデプロイメント環境、つまり、複数のレプリケートされたサーバー・プロセスおよび複数のグループで適切に機能するようにする方法。UniversityおよびBillingの各サーバー・プロセスがレプリケートされている場合の設計では、これら2つのオブジェクトをどのようにインスタンス化するかを考慮する必要があります。これらの考慮事項の主要な意味は、これらのオブジェクトが次の項目を満たす必要があるということです。
以降の項では、これらの検討事項およびその内容について詳しく説明します。
Productionサンプル・アプリケーションの前に扱ったUniversityサーバー・アプリケーションでは、Registrar
およびTeller
オブジェクトの実行時の振る舞いは簡単なものでした。
しかし、UniversityおよびBillingサーバー・プロセスがレプリケートされると、Oracle TuxedoドメインにはRegistrar
およびTeller
オブジェクトの複数のインスタンスを区別する方法が必要になります。つまり、1つのグループで2つのUniversityサーバー・プロセスが実行中である場合、Oracle Tuxedoドメインには、いわば、1番目のUniversityサーバー・プロセスで実行中のRegistrar
オブジェクトと、2番目のUniversityサーバー・プロセスで実行中のRegistrar
オブジェクトを区別するための方法が必要になります。
これらのオブジェクトの複数のインスタンスを区別する機能をOracle Tuxedoドメインに与える方法は、オブジェクトの各インスタンスを一意にすることです。
各Registrar
およびTeller
オブジェクトを一意のものにするには、これらのオブジェクトのファクトリで、これらに対するオブジェクト参照を作成する方法を変更しなければなりません。たとえばBasicサンプル・オブジェクトでは、RegistrarFactory
オブジェクトがRegistrar
オブジェクトへのオブジェクト参照を作成すると、TP::create_object_reference()
操作が、文字列registrar
のみからなるOIDを指定していました。しかし、Productionサンプル・アプリケーションでは、同じTP::create_object_reference()
操作が、生成された一意のOIDを使用します。
Registrar
およびTeller
オブジェクトのそれぞれに一意のOIDを付与した結果、これらのオブジェクトの複数のインスタンスが、Oracle Tuxedoドメインの中で同時に実行できるようになりました。この特性はステートレス・オブジェクト・モデルに典型的なもので、Oracle Tuxedoドメインのスケーラビリティを高めつつ、高いパフォーマンスを提供する方法の例でもあります。
そして最後に、一意のRegistrar
およびTeller
オブジェクトはクライアント・リクエストごとにメモリーに格納される必要があるため、これらのオブジェクトへの呼出しが完了したときには、オブジェクトの状態がメモリー上でアイドル状態となって残らないように、オブジェクトを非アクティブ化することが非常に重要になります。Productionサーバー・アプリケーションでは、ICFファイルでこれら2つのオブジェクトにmethod
アクティブ化ポリシーを割り当てることで、この問題を解決しています。
レプリケートされたサーバー・グループを使用することでスケーラビリティについて得られる最大の利点は、複数のマシンに処理を分散できることです。しかし、Universityサンプル・アプリケーションの場合のように、アプリケーションがデータベースと対話する場合は、これら複数のサーバー・グループがデータベースとの対話に与える影響を考慮することが重要です。
多くの場合、デプロイされているマシンに、データベースは1つずつ関連付けられています。サーバー・アプリケーションが複数台のマシンに分散されている場合は、データベースをどのようにセットアップするかを検討する必要があります。
この章で説明しているように、Productionサンプル・アプリケーションでは、2つのデータベースを使用します。しかし、このアプリケーションは、簡単にそれ以上のデータベースに対応できるよう構成できます。使用するデータベースの数は、システム管理者が決定してください。
Productionサンプル・アプリケーションでは、学生および口座の情報は、2つのデータベース間に分割されますが、コース情報は同一です。コース情報は、コース登録用途では読取り専用となっているため、両方のデータベースのコース情報が同一であることは問題にはなりません。一方で、学生情報および口座情報については読書きが行われます。複数のデータベースが学生および口座についても同一のデータを格納するとしたら(つまり、データベースが分割されていない場合)、アプリケーションでは、学生情報または口座情報が変更されるたびにデータベース全体にわたって学生および口座の情報の更新を同期する処理のオーバーヘッドに対処する必要が生じるでしょう。
Productionサンプル・アプリケーションは、ファクトリ・ベース・ルーティングによって、1台のマシンにリクエストの1セットを、別のマシンにリクエストの別の1セットを送信します。先に説明したように、ファクトリ・ベース・ルーティングは、Registrar
オブジェクトの参照が作成されている方法によってRegistrarFactory
オブジェクトに実装されています。
たとえば、クライアント・アプリケーションがRegistrarFactory
オブジェクトにリクエストを送信して、Registrar
オブジェクトのオブジェクト参照を取得した場合、クライアント・アプリケーションはそのリクエストに学生IDを含めます。ファクトリによって返されたオブジェクト参照はグループ固有のものであるため、クライアント・アプリケーションは、RegistrarFactory
オブジェクトが返すオブジェクト参照を使用して、その後のRegistrar
オブジェクトへのすべての呼出しを、特定の学生のために行う必要があります。したがって、たとえばクライアント・アプリケーションがその後、Registrar
オブジェクトに対してget_student_details()
操作を呼び出すと、クライアント・アプリケーションでは、Registrar
オブジェクトが、その学生のデータを格納しているデータベースと関連付けられたサーバー・グループにおいて、確実にアクティブ化されます。この機能を示すために、Productionサンプル・アプリケーションに実装されている以下の実行シナリオを検討してみます。
RegistrarFactory
オブジェクトのfind_registrar()
操作を呼び出します。この要求には学生ID 1000003が含まれます。 RegistrarFactory
オブジェクトにルーティングします。RegistrarFactory
オブジェクトは、UBBCONFIG
ファイルのルーティング情報に基づいて、学生IDを使用してORA_GRP1のRegistrar
オブジェクトへのオブジェクト参照を作成し、このオブジェクト参照をクライアント・アプリケーションに返します。register_for_courses()
操作を呼び出します。 Registrar
オブジェクトをインスタンス化し、それにクライアント呼出しを送信します。 前述のシナリオのRegistrarFactory
オブジェクトがクライアント・アプリケーションに返すのは、ORA_GRP1でだけインスタンス化できるRegistrar
オブジェクトへの一意の参照です。ORA_GRP1はProductionマシン1で実行されていて、学生IDが100001 - 100005の範囲の学生に関するデータが格納されているデータベースを利用します。このため、続けてクライアント・アプリケーションが学生に関するRegistrar
オブジェクトへのリクエストを送信したとき、Registrar
オブジェクトは適切なデータベースとやり取りができます。
Registrar
オブジェクトでTeller
オブジェクトが必要になると、Registrar
オブジェクトはTellerFactory
オブジェクトを呼び出します。このとき、University ServerオブジェクトでキャッシュされているTellerFactory
オブジェクト参照が使用されます。詳細は、「Tellerオブジェクトへのリクエストの送信」を参照してください。
ただし、TellerFactory
オブジェクトではファクトリ・ベース・ルーティングが使用されているため、Registrar
オブジェクトがTeller
オブジェクトへの参照を要求するとき、Registrar
オブジェクトは学生の口座番号を渡します。このようにしてTellerFactory
オブジェクトは、正しいデータベースを備えたグループ内のTeller
オブジェクトへの参照を作成します。
注: | Productionサンプル・アプリケーションが適正に動作するためには、システム管理者がサーバー・グループとデータベースの構成を正しく行うことが不可欠です。具体的には、システム管理者はルーティング表で指定されたルーティング基準と、これらの基準を使用したリクエストのルーティング先となるデータベースを、確実に一致させる必要があります。Productionサンプルを例にすると、指定されたグループにあるデータベースは、そのグループにルーティングされたリクエストに正しく対応する学生情報および口座情報を含んでいる必要があります。 |
将来的には、Productionサンプル・アプリケーションのシステム管理者がOracle Tuxedoドメインの容量を増やす必要を感じる場合もあります。たとえば、Universityで学生数が大幅に増加した場合や、7つのキャンパスがある大学の全体のコース登録処理を扱えるようにProductionアプリケーションをスケール・アップする場合などが考えられます。これを行うのに、アプリケーションを修正したり再ビルドしたりする必要はありません。
継続的に容量を追加するために、システム管理者には以下のツールが用意されています。
UBBCONFIG
ファイルを変更する必要があります。サーバー・プロセスが実行されるグループを追加し、グループでどのサーバー・プロセスを実行するか指定してから、どのマシンで実行するかを指定してください。
たとえば、この章で示したように2つのグループへルーティングするかわりに、システム管理者がUBBCONFIG
ファイルでルーティング・ルールを変更することで、Oracle Tuxedoドメインに追加された新しいグループの間でアプリケーションの処理をさらに分離することが可能です。ルーティング表へのすべての変更は、UBBCONFIG
ファイルで構成されているサーバー・グループおよびマシンに対するすべての変更および追加と整合している必要があります。
注: | データベースを使用するアプリケーションの容量を増やす場合、特にファクトリ・ベース・ルーティングを使用しているときには、データベースの設定に与える影響を検討する必要があります。たとえば、Productionサンプル・アプリケーションが6台のマシン間に分散している場合は、UBBCONFIG ファイルのルーティング表に基づいて、適切に各マシンのデータベースを設定する必要があります。 |
一般に、ステートレス・オブジェクトを実装する際のコストと、ステートフル・オブジェクトを実装する際のコストを比較する必要があります。
オブジェクトをその永続状態で初期化するコストが高い場合(これは、たとえば、そのオブジェクトのデータが大きな領域を占めている場合や、永続状態の場所が、それをアクティブ化するサーバントから大幅に離れたディスク上である場合ですが)、たとえオブジェクトが会話の間アイドル状態であるとしても、オブジェクトをステートフルにしておく方が合理的です。オブジェクトをアクティブ化されたままにしておくコストが、マシンのリソース使用率との関連で高額になる場合は、そのようなオブジェクトをステートレスにするほうが合理的です。
オブジェクトの状態を、アプリケーションに合わせて効率的かつ適切な方法で管理することにより、アプリケーションの能力を最大限に高めて、多数のオブジェクトを使用する多数のクライアント・アプリケーションを同時にサポートできます。一般には、こうした目的のために、オブジェクトに対してmethod
アクティブ化ポリシーを割り当てます。こうすることによって、アイドル状態のオブジェクト・インスタンスが非アクティブ化され、マシンのリソースをほかのオブジェクト・インスタンスに割り当てられるようになります。ただし、使用するアプリケーション固有の特性および要件は、アプリケーションごとに異なります。
注: | Oracle Tuxedoリリース8.0以降では、パフォーマンスの拡張として、パラレル・オブジェクトのサポートが提供されています。この機能を利用すると、特定アプリケーションのすべてのビジネス・オブジェクトをステートレス・オブジェクトにすることができます。詳細は、『CORBAプログラミング・リファレンス』の第3章「TPフレームワーク」を参照してください。 |
サーバー・リソースはオブジェクトがアイドル状態のときには絶対に使用されないため、ステートレス・オブジェクトは一般に、サーバー・リソースのパフォーマンスを向上させ、最適な使い方を実現します。ステートレス・オブジェクトは、一般に、サーバー・アプリケーションの実装に適した手法です。ステートレス・オブジェクトは、特に以下の状況に適しています。
オブジェクトをステートレスにすることで、サーバー・アプリケーションのリソースがクライアント・アプリケーションからの入力の待機のために不定期に長時間拘束されないようにできます。
ステートレス・オブジェクト・モデルを使用するアプリケーションでは、次の特性に注意してください。
ステートフル・オブジェクトは、いったんアクティブ化されると、オブジェクトが存在しているプロセスが停止されたり、オブジェクトがアクティブ化されているトランザクションが完了したりといった、特定のイベントが発生するまで、メモリー内にとどまります。
ステートフル・オブジェクトは、一般に以下の状況に適しています。
注: | プロセス・オブジェクトをトランザクションにどのように関与させるかについては、注意深く検討してください。トランザクションに関与しているすべてのオブジェクトは、ほかのクライアント・アプリケーションまたはオブジェクトから呼び出せません。プロセス・オブジェクトは多数のクライアント・アプリケーションによって利用されるので、トランザクションに対して頻繁に、または長期間関与すると、問題の原因になる可能性があります。 |
ステートフル・オブジェクトの以下の振る舞いに注意してください。
たとえば、1つのオブジェクトがデータベースにロックを保持し、大量のデータをメモリーにキャッシュしている場合、そのステートフル・オブジェクトによって使用されているデータベースおよびメモリーは、トランザクションが完了するまでほかのオブジェクトでは利用できません。