Oracle Tuxedo/Qコンポーネントを使用すると、メッセージを永続的な記憶域(ディスク)や一時的な記憶域(メモリー)のキューに登録でき、後で取り出して処理できます。Oracle Tuxedoアプリケーション・トランザクション・モニター・インタフェース(ATMI)を使用して、キューへのメッセージの登録、またはキューからのメッセージの取出しを行う関数を実行できます。応答メッセージおよびエラー・メッセージは、キューに登録されて、後でクライアント・プログラムに返されます。管理コマンドのインタプリタを使用すると、キューの作成、表示、および変更を行うことができます。また、サーバーを使用して、メッセージのキューへの登録、キューからの取り出し、キューからの転送、およびキューに関係するトランザクション管理のリクエストを受け取ることができます。
図1-1は、キュー機能のコンポーネントを示しています。
この図は、キュー・サービスの呼出しで、キュー・システムの各コンポーネントがどのように動作するかを示しています。ここでは、この図を使用して、管理者とプログラマがOracle Tuxedo /Qコンポーネントを定義したり、メッセージをキューに入れて処理したり、応答を受け取る方法について説明します。図に示されているコンポーネントのサブセットを使用すると、単純なピア・ツー・ピア通信でキュー・サービスを使用できます。
キュー・スペースは、1つのリソースです。このリソースには、X/OpenのXA準拠のリソース・マネージャ・インタフェースからアクセスできます。このインタフェースは、別のXA準拠のリソース・マネージャと連携して、キューへの登録およびキューからの取出しが2フェーズ・コミット・トランザクションの一部として行われるために必要です。
Oracle Tuxedoの管理者は、サーバーを定義し、図「キュー・サービスの呼出し」で縦の2本の破線の間に示されているキュー・スペースおよびキューを作成する必要があります。
キュー・サーバー・グループは、最低1つ定義します。その場合、TMS_QM
をトランザクション・マネージャ・サーバーにします。
このほかに、システムで提供される2つのサーバーを構成ファイルに定義する必要があります。この2つのサーバーは、次の処理を行います。
main()
が用意されています。この関数は、サーバーの初期化と終了、サービス・ルーチンへの着信リクエストの受信とディスパッチを行うためのバッファの割り当て、応答の正しい宛先へのルーティングを行います。この処理はすべてアプリケーションに透過的です。既存のサーバーは、自分のメッセージをキューから取り出したり、応答をキューに登録することは行いません。Oracle Tuxedo /Qの目的の1つは、そのような既存のサーバーを変更せずに、キューに登録されたメッセージに対して既存のサーバーを利用できるようにすることです。TMQFORWARD
サーバーは、キュー・スペース内の1つ以上のキューからメッセージを取り出し、そのメッセージをキューと同じ名前のサービスを持つサーバーに送信し、応答を待ちます。そして、発信元によって応答キューまたは異常終了キューが指定されている場合はメッセージの発信元の指定に従って、対応する応答キューまたは異常終了キューに、正常終了応答または異常終了応答を登録します。また、管理者は、キュー管理プログラムqmadmin(1)またはAPPQ_MIB(5)管理情報ベース(MIB)を使用して、キュー・スペースを作成する必要があります。キュー・スペースには、キューが格納されます。たとえば、図「キュー・サービスの呼出し」では、APPキュー・スペース内に4つのキューが存在しています。各キュー・スペースはリソース・マネージャ・インスタンスであり、1つのグループに単一のリソース・マネージャ(RM)だけが存在できるため、キュー・スペースとキュー・サーバー・グループは1対1のマッピングです。
キュー・スペースの概念では、次に示す方法で、キュー間でオーバーヘッドを共有することにより、キューに対応する管理オーバーヘッドを減少させることができます。
TMQUEUE
は、単一のキュー・スペース内で、複数のキューに対してメッセージの登録と取出しを行います。TMQFORWARD
は、単一のキュー・スペース内で、複数のキューに対してメッセージの取出しと転送を行います。「キュー・サービスの呼出し」
のトランザクション・マネージャ・サーバーTMS_QMの2つのインスタンスは、単一のキュー・スペース内で、複数のキューに対してトランザクションを実行します。トランザクション・マネージャ・サーバーの1つのインスタンスは、非ブロッキング・トランザクション用に予約されています。そのため、高速で処理され、ブロッキング・トランザクションによって遅延されません。ブロッキング・トランザクションはトランザクション・マネージャ・サーバーの2番目のインスタンスで処理されます。 管理者は、キュー・スペースに対して、アプリケーション構成内に単一のサーバー・グループを定義できます。その場合、UBBCONFIG
にグループを指定するか、またはtmconfig(1)
を使用して(「tmconfig、wtmconfig(1)」を参照)、グループを動的に追加します。
キューを定義する作業の1つに、キューのメッセージの順序を指定することがあります。キューの順序付けは、メッセージの可用期間、有効期限、優先度、FIFO
、LIFO
のいずれか、またはこれらの組合せで決定します。
管理者は、この中から1つ以上の基準を指定します。その場合、最上位の基準から先に指定します。FIFO
およびLIFO
の値は、最後に指定します。メッセージは、指定された順序付け基準に従ってキューに登録され、キューの先頭から取り出されます。管理者は、必要な数だけメッセージ・キュー・サーバーを設定して、クライアントが安定キューに生成するリクエストに対応できるようにします。
データ依存型ルーティングは、同じサービスを提供するサーバーが存在する複数のサーバー・グループ間でルーティングを行うために使用します。
管理上の目的から、定期的に取り出されないキューがしきい値に達したときに実行されるコマンドを設定できます。これは、キューに使用されるキュー・スペースのバイト数、ブロック数、または割合、あるいはキューのメッセージの数に基づいて設定します。このコマンドでは、TMQFORWARD
サーバーを起動してキューを取り出すか、または管理者にメールを送信して手動で処理します。
Oracle Tuxedoシステムでは、Oracle Tuxedoインフラストラクチャのキューイング・サービス・コンポーネントを使用して、いくつかの操作が行われます。(Oracle Tuxedoインフラストラクチャは、セキュリティ、スケーラビリティ、キュー処理、トランザクションなどのサービスを提供します。)たとえば、共用メモリーの管理操作は、Queuing Servicesコンポーネントで提供されます。Oracle Tuxedoアプリケーションで現在使用できない関数もあります。それらについては、その関数の説明で注意してあります。
キュー機能をクライアント間のピア・ツー・ピア通信で使用すると、クライアントは転送サーバーを使用せずに、他のクライアントと通信できます。図1-2は、ピア・ツー・ピア通信モデルを示しています。
図「キュー・サービスの呼出し」のステップ1 - 3で、tpenqueue(3c)
を使用して、クライアントはアプリケーション・キュー・スペース内のSERVICE1キューにメッセージを登録します。オプションとして、tpenqueue()
の呼出しに、応答キューおよび異常終了キューの名前を含めることができます。この例では、これらはキューCLIENT_REPLY1
およびFAILURE_Q
になっています。クライアントは、メッセージに付ける相関識別子の値を指定することもできます。この値は、キュー間で同じです。そのため、キューのメッセージに関連付けられたどの応答メッセージまたは異常終了メッセージも、応答キューまたは異常終了キューから読み取られるときに識別できます。
クライアントは、デフォルトのキューの順序付け(たとえば、メッセージがキューから取り出せるようになるまでの時間)を使用するか、デフォルトのキューの順序付けを無効にすること(たとえば、メッセージをキューの先頭に置くこと、またはキュー上の別のメッセージの前に置くことを要求すること)ができます。tpenqueue
()は、TMQUEUE
サーバーにメッセージを送信し、そのメッセージはキューに登録され、承認(ステップ3)がクライアントに送信されます。肯定応答は、クライアントが直接確認することはできません。ただし、クライアントが正常な戻り値を取得すると、肯定応答が送られたと見なすことができます。(異常終了の戻り値には、異常終了の内容についての情報が含まれています。)
キュー・マネージャによって割り当てられたメッセージ識別子は、アプリケーションに返されます。この識別子は、特定のメッセージをキューから取り出す場合に使用します。また、この識別子は、別のtpenqueue()
内で使用して、キューに次に登録されるメッセージの前にあるメッセージを識別することができます。
キューに登録されたメッセージをキューから取り出すには、そのメッセージをキューに登録したトランザクションが正常にコミットされている必要があります。
Oracle Tuxedo /Qをキュー・サービスの呼出しに使用している場合に、メッセージがキューの先頭に到達すると、TMQFORWARD
サーバーはそのメッセージをキューから取り出し、tpcall(3c)を介してキューと同じ名前を持つサービスに転送します。図「キュー・サービスの呼出し」では、このキューとサービスはSERVICE1
という名前で、ステップ4、5、および6がそれを示しています。クライアントの識別子、およびアプリケーションの認証キーは、メッセージをキューに登録したクライアントに設定されます。この2つは、キューから取り出されたメッセージがサービスに送信されるときに、そのメッセージに付加されます。
サービスが応答を返すと、TMQFORWARD
はその応答(オプションとしてユーザー戻りコードを伴う)を応答キューに登録します(図「キュー・サービスの呼出し」のステップ7を参照)。
その後(図「キュー・サービスの呼出し」のステップ8、9、および10)、クライアントはtpdequeue(3c)を使用して、応答キューCLIENT_REPLY1
から読み込んで応答メッセージを取得します。
tpdequeue()
にTPQPEEKフラグを設定すると、メッセージをキューから削除せずに取り出すことができます。有効期限が過ぎたメッセージ、または管理者によって削除されたメッセージは、直ちにキューから削除されます。
トランザクション管理の目的の1つは、グローバル・トランザクション内でメッセージをキューに登録したりキューから取り出して、信頼性を確実にすることです。ただし、これとは相反する目的として、関与するトランザクションの数を最小限にして実行のオーバーヘッドを減少させることがあります。
呼出し側は、キュー処理を呼出し側のトランザクションから分離して、自身が関与しているあらゆるトランザクションとは別のトランザクションで、メッセージをキューに登録することもできます。ただし、この場合のタイムアウトは、メッセージがキューに登録されているかどうかにかかわらず、認識されません。
適切なな法としては、図1-3に示すように、呼出し側のトランザクション内でメッセージをキューに登録します。
この図では、クライアントがトランザクションを開始し、メッセージをキューに登録し、トランザクションをコミットしています。メッセージは、TMQFORWARD
で開始される2番目のトランザクション内でキューから取り出されます。サービスはtpcall(3c)で呼び出されて実行され、応答が同じトランザクション内でキューに登録されます。クライアントは3番目のトランザクションを開始し、応答をキューから取り出します。また、別のリクエスト・メッセージをキューに登録する場合もあります。次のリクエストのキューへの登録は、前のリクエストからのレスポンスをキューから取り出す処理と同じトランザクション内で行うことができます。そのため、実行中の処理では、3番目と最初のトランザクションを1つにまとめることができます。
注: | システムでは、同じトランザクション内で、あるメッセージからのレスポンスをキューから取り出し、次のリクエストをキューに入れることが可能です。ただし、同じトランザクション内で、リクエストをキューに入れ、レスポンスをキューから取り出すことはできません。メッセージをキューから取り出すには、リクエストをキューに登録するトランザクションが正常にコミットされることが必要です。 |
応答メッセージは、tpenqueue()
の呼出し時に、アプリケーションによって指定することもしないことも可能です。その場合、それぞれ次のような結果になります。
tpdequeue()
を使用してメッセージを明示的にキューから取り出す場合、そのアプリケーションはtpenqueue()
を呼び出して応答をキューに登録する必要があります。通常、これはリクエスト・メッセージがキューから取り出されて実行されるのと同じトランザクション内で行われます。そのため、この操作全体はアトミックに行われます。つまり、トランザクションが成功した場合にのみ、応答がキューに登録されます。TMQFORWARD
によってメッセージが自動的に処理される場合(キューから取り出され、tpcall()
を介してアプリケーションに渡される場合)、アプリケーション・サービスが正常に終了したとき、つまりTPSUCCESS
が設定されてtpreturn(3c)が呼び出され、tpcall()
が1を返さなかったときは、TMQFORWARD
は応答をキューに登録します。tpcall()
がデータを受け取ると、使用された型付きバッファは応答キューに登録されます。tpcall()
でデータが受信されなかった場合、データなしのメッセージ(つまり、NULLメッセージ)が、キューに登録されます。メッセージがキューに登録されることは、それがNULLであっても、操作の完了を示すには十分です。エラーを処理するには、アプリケーションに起こるエラーの特徴を理解することと、Oracle Tuxedo管理者とアプリケーション・プログラム開発者の注意深い計画と協力が必要です。Oracle Tuxedo /Qでは、メッセージがトランザクション内でキューから取り出され、そのトランザクションがロールバックされたときに、再試行パラメータが0より大きい場合は、メッセージがキューに戻されて、再度取出しと実行が可能になります。
一時的な障害の場合は、少し時間をおいてから、メッセージの取出しと実行を再試行します。たとえば、アプリケーション・データベースに対するアクティビティが多数ある場合は、別のトランザクションによってデータベースのロックが解除されるには、少しの時間さえあればよい場合があります。通常、再試行の回数に上限を設定することも、なんらかのアプリケーション不備によってリソースを著しく浪費することを防ぐには有用です。管理者がキューを設定するときに、再試行の回数と遅延時間(秒単位)の両方を指定できます。再試行の回数0は、再試行が行われないことを示します。再試行の回数が上限に達すると、管理者がキュー・スペースに設定するエラー・キューにメッセージが移動されます。
障害が一時的なものではない場合もあります。たとえば、キュー・メッセージが存在しないアカウントに対して操作をリクエストする場合などです。その場合、再試行してリソースを浪費しないようにします。アプリケーション・プログラマまたは管理者が、特定の操作の失敗が一時的ではないと判断した場合、単に再試行の回数を0に設定します。同じサービスに対する障害が、一時的なものであったり、永続的なものであったりする場合がよくあります。管理者およびアプリケーション開発者は、いろいろな方法でエラーに対処できるようにしておきます。
アプリケーションは、直接メッセージをキューから取り出すことも、TMQFORWARD
サーバーを使用することもできます。また、トランザクションをコミットするようにロジックで指示されている場合に、トランザクションがロールバックされたり、メッセージがキューに再度登録されたりするエラーが発生することがあります。このような問題とその対処法については、「Oracle Tuxedo /Qの管理」、「Oracle Tuxedo /QのC言語プログラミング」、および「Oracle Tuxedo/Q COBOL言語プログラミング」を参照してください。
Oracle Tuxedo /QによってOracle Tuxedoアプリケーション・プログラマおよび管理者に提供される機能は、次のようにまとめることができます。
キューに登録されたメッセージを使用するアプリケーション・パラダイムは多数あります。このようなパラダイムでは、マシン、サーバー、またはリソースが使用できない場合、または信頼性が低い場合(広域ネットワークやワイヤレス・ネットワークの場合など)に、リクエストをキューに登録できます。また、ワーク・フローで、プロセスの次のステップを行うために各ステップでキュー・リクエストを生成できます。さらに、処理に時間がかかるトランザクションのバッチ処理で、発信元が完了を待たなくても、最終的にはメッセージが処理されたことを保証できます。ピア・ツー・ピア関係で、関係がない2つのアプリケーション間で、データ・パイプを提供することもできます。