メッセージ交換の優先度

メッセージ交換の優先度は一連のユーザー定義ルールであり、これらの各ルールによって、優先度レベルと、その優先度レベルを割り当てる Service Broker メッセージ交換を判断するための条件を指定します。通常、優先度が高いメッセージ交換のメッセージは、優先度が低いメッセージ交換のメッセージよりも先に送受信されます。

メッセージ交換の優先度の使用

メッセージ交換の優先度を使用すると、次のことができます。

  • 他のメッセージ交換よりも優先されるメッセージ交換を指定する。

  • 異なるサービス階層をサポートし、支払いの割合が高い顧客からのメッセージが、支払いの割合が低い顧客からのメッセージよりも先に送信されるようにする。

  • 顧客の要求をバックグラウンド タスクよりも優先させる。たとえば、新規顧客の登録は、ビジネス トランザクション サマリをデータ ウェアハウスに送信するタスクよりも優先させる必要があります。

メッセージ交換の優先度とメッセージ交換エンドポイント

メッセージ交換の優先度は、各データベースで CREATE BROKER PRIORITY ステートメントを使用して作成されます。各メッセージ交換の優先度は次の内容を定義します。

  • メッセージ交換の優先度の名前。

  • Service Broker メッセージ交換に割り当てる優先度レベル。レベルは、1 (最も低い) から 10 (最も高い) までの整数で指定します。既定値は 5 です。

  • 優先度レベルが割り当てられるメッセージ交換を判断する条件。

    • コントラクト名、または ANY

    • ローカル サービス名、または ANY

    • リモート サービス名、または ANY

Service Broker では、メッセージ交換エンドポイントが作成されるときに、それらのエンドポイントに優先度レベルを割り当てます。各メッセージ交換には、2 つのメッセージ交換エンドポイントがあります。

  • 発信側メッセージ交換エンドポイントは、メッセージ交換の一方を発信側サービスおよび発信側キューに関連付けます。発信側メッセージ交換エンドポイントは、BEGIN DIALOG ステートメントが実行されたときに作成されます。発信側メッセージ交換エンドポイントに関連付けられる操作には、次のものがあります。

    • 発信側サービスから送信する。

    • 発信側キューから受信する。

    • 発信側キューから次に使用できるメッセージ交換グループを取得する。

  • 発信先メッセージ交換エンドポイントは、メッセージ交換の相手側を発信先のサービスおよびキューに関連付けます。発信先メッセージ交換エンドポイントは、発信側からの最初のメッセージが発信先キューに入れられたときに作成されます。発信先メッセージ交換エンドポイントに関連付けられる操作には、次のものがあります。

    • 発信先キューから受信する。

    • 発信先サービスから送信する。

    • 発信先キューから次に使用できるメッセージ交換グループを取得する。

どのサービスがローカルまたはリモートのサービスになるかは、メッセージ交換エンドポイントの種類によって決まります。

  • 発信側メッセージ交換エンドポイントの場合は、発信側サービスがローカル サービスであり、発信先サービスがリモート サービスです。

  • 発信先メッセージ交換エンドポイントの場合は、発信先サービスがローカル サービスであり、発信側サービスがリモート サービスです。

Service Broker が優先度レベルを割り当てるしくみ

Service Broker では、メッセージ交換エンドポイントが作成されるときに、メッセージ交換の優先度レベルを割り当てます。メッセージ交換エンドポイントでは、メッセージ交換が終了するまでその優先度レベルが保持されます。新しい優先度や、既存の優先度に対する変更は、既存のメッセージ交換には適用されません。

Service Broker でメッセージ交換エンドポイントに割り当てる優先度レベルは、そのエンドポイントのプロパティに最も一致するコントラクトおよびサービスの条件を持つメッセージ交換の優先度の優先度レベルです。その検索順序を次の表に示します。

エンドポイント コントラクト

エンドポイント ローカル サービス

エンドポイント リモート サービス

優先コントラクト

優先ローカル サービス

優先リモート サービス

優先コントラクト

優先ローカル サービス

ANY

優先コントラクト

ANY

優先リモート サービス

優先コントラクト

ANY

ANY

ANY

優先ローカル サービス

優先リモート サービス

ANY

優先ローカル サービス

ANY

ANY

ANY

優先リモート サービス

ANY

ANY

ANY

Service Broker では、指定されたコントラクト、ローカル サービス、およびリモート サービスが、メッセージ交換エンドポイントで使用されるものと一致する優先度を最初に検索します。その優先度が見つからなかった場合、Service Broker では、コントラクトおよびローカル サービスがエンドポイントで使用されるものと一致し、かつリモート サービスが ANY と指定された優先度を検索します。この検索を、上の表に示されているすべての組み合わせに対して継続します。一致する優先度が見つからない場合、そのエンドポイントには既定の優先度 5 が割り当てられます。

Service Broker の通信プロトコルは、メッセージ交換エンドポイント間で優先度レベルを転送しません。Service Broker では、各エンドポイントに優先度レベルを個別に割り当てます。Service Broker で発信側と発信先の両方のメッセージ交換エンドポイントに優先度レベルを割り当てるようにするには、両方のエンドポイントをメッセージ交換の優先度に含める必要があります。発信側と発信先のメッセージ交換エンドポイントが別々のデータベースにある場合、各データベースでメッセージ交換の優先度を作成する必要があります。発信側と発信先のエンドポイントが同じデータベースにある場合は、次のようになります。

  • メッセージ交換で使用されるコントラクト名を指定し、ローカルおよびリモートのサービス名に ANY を指定する、1 つのメッセージ交換の優先度を使用することで、両方のメッセージ交換エンドポイントを含めることができます。

  • 2 つのメッセージ交換の優先度を使用して、各メッセージ交換エンドポイントを個別に含めることができます。

    • LOCAL_SERVICE_NAME に発信側サービス名を指定し、REMOTE_SERVICE_NAME に発信先サービス名を指定する、発信側エンドポイント用の 1 つのメッセージ交換

    • LOCAL_SERVICE_NAME に発信先サービス名を指定し、REMOTE_SERVICE_NAME に発信側サービス名を指定する、発信先エンドポイント用の 1 つのメッセージ交換

通常は、メッセージ交換の両方のエンドポイントに対して同じ優先度レベルを指定します。各エンドポイントに異なる優先度レベルを指定することは可能ですが、そのように指定しても、ある方向のメッセージが別の方向のメッセージよりも速く送信されるわけではありません。メッセージは、一方のメッセージ交換エンドポイントから送信され、もう一方のエンドポイントで受信されます。したがって、各メッセージの転送は、両方のエンドポイントに割り当てられた優先度レベルに影響されます。たとえば、発信側メッセージ交換エンドポイントの優先度レベルが 10、発信先エンドポイントの優先度レベルが 1 になるように、メッセージ交換を構成したとします。この場合、次のようになります。

  • 発信側サービスから優先度レベル 10 を使用して転送されたメッセージは、発信先キューで優先度レベル 1 を使用して受信されます。

  • 発信先サービスから優先度レベル 1 を使用して転送されたメッセージは、発信側キューで優先度レベル 10 を使用して受信されます。

メッセージ交換グループには、次の条件に当てはまる任意のメッセージ交換に割り当てられた、最も高い優先度と同じ優先度が割り当てられます。

  • そのグループのメンバである。

  • メッセージが現在サービス キュー内に存在する。

データベースでメッセージ交換の優先度が作成されていない場合は、データベース内のすべてのメッセージ交換エンドポイントに、既定の優先度 5 が割り当てられます。

メッセージ交換の優先度は、メッセージの転送に影響を与えません。メッセージの転送は、常に既定の優先度 5 で動作します。

メッセージ交換の優先度の例

次の要素が備わったシステムについて考えてみます。

  • InitiatorServiceInitiatorQueue を含む InitiatorDB

  • TargetServiceTargetQueue を含む TargetDB

  • SimpleContract という名前のコントラクト。このコントラクトは、RequestMessagesInitiatorService から TargetService に送信されることを指定します。また、ReplyMessagesTargetService から InitiatorService に送信されることも指定します。

次のスクリプトは、発信側メッセージ交換エンドポイントとそれに関連する次の操作の優先度レベルを指定します。

  • InitiatorService から TargetQueue への RequestMessage の SEND

  • InitiatorQueue からの ReplyMessage の RECEIVE

USE InitiatorDB;
GO
CREATE BROKER PRIORITY InitiatorToTargetPriority
    FOR CONVERSATION
    SET (CONTRACT_NAME = SimpleContract,
         LOCAL_SERVICE_NAME = InitiatorSerivce,
         REMOTE_SERVICE_NAME = N'TargetService',
         PRIORITY_LEVEL = 3);
GO

次のスクリプトは、発信先メッセージ交換エンドポイントとそれに関連する次の操作の優先度レベルを指定します。

  • TargetQueue からの RequestMessage の RECEIVE

  • TargetService から InitiatorQueue への ReplyMessage の SEND

USE TargetDB;
GO
CREATE BROKER PRIORITY TargetToInitiatorPriority
    FOR CONVERSATION
    SET (CONTRACT_NAME = SimpleContract,
         LOCAL_SERVICE_NAME = TargetService,
         REMOTE_SERVICE_NAME = N'InitiatorService',
         PRIORITY_LEVEL = 3);
GO

優先度のしくみ

通常、Service Broker では優先度が高いメッセージ交換のメッセージを、優先度が低いメッセージ交換のメッセージよりも先に送受信します。優先度が高いメッセージ交換のメッセージがキューに含まれる時間は、優先度が低いメッセージ交換のメッセージよりも短くなります。

受信の優先度レベル

優先度レベルは、メッセージまたはメッセージ交換グループ ID をキューから受信する操作に常に適用されます。

優先度レベルは、RECEIVE によって取得される一連のメッセージと、メッセージを取得する順序を判断する要因の 1 つです。

  • 各 RECEIVE ステートメントでは、常に 1 つのメッセージ交換グループのメッセージが取得されます。

    • WHERE 句がない RECEIVE では、キュー内にメッセージがある、ロックされていないメッセージ交換グループのうちの最も優先度が高いグループのメッセージが取得されます。

    • WHERE 句がある RECEIVE では、WHERE 句で指定されたメッセージ交換グループのメッセージが取得されます。

  • メッセージ交換グループ内では、グループ内のメッセージ交換の優先度レベルに基づいて、メッセージが取得されます。最初に最も優先度が高いメッセージ交換のすべてのメッセージが取得され、続いてその次に優先度が高いメッセージ交換のメッセージが取得されます。

  • メッセージ交換内では、メッセージが送信されたときの順序と同じ順序で取得されます。

GET CONVERSATION GROUP は、キュー内にメッセージがある一連のロックされていないグループから、最も優先度が高いグループを返します。

転送の優先度レベル

インスタンスの転送キュー内のメッセージは、次の内容に基づいて順番に転送されます。

  • 関連するメッセージ交換エンドポイントの優先度レベル

  • 優先度レベル内では、メッセージ交換における送信順序

Service Broker は、データベース エンジンのインスタンス内にあるすべての転送キュー間で、優先度レベルを調整します。Service Broker は、最初にすべての転送キュー内にある優先度 10 のメッセージ交換のメッセージを転送し、次に優先度 9 のメッセージ交換のメッセージを転送します。

優先度レベルの差異により、メッセージ パフォーマンスの相対的な差異が大きくなります。たとえば、9 と 10 のように、隣接する 2 つの優先度レベルを使用するシステムでは、最も優先度が高いメッセージのパフォーマンス上の優位性は小さくなります。一方、1 と 10 のように、大きく離れた 2 つの優先度レベルを使用するシステムでは、最も優先度が高いメッセージのパフォーマンス上の優位性は大きくなります。複数の優先度レベルを使用するシステムでは、ほとんどの処理は上位 2 つまたは 3 つの優先度レベルに割り当てられます。

メッセージ交換の優先度で指定された優先度レベルは、HONOR_BROKER_PRIORITY データベース オプションが ON に設定されている場合にのみ、転送キュー内のメッセージに割り当てられます。HONOR_BROKER_PRIORITY データベース オプションが OFF に設定されている場合、そのデータベースの転送キューに配置されたすべてのメッセージは、既定の優先度レベル 5 を使用して送信されます。sys.transmission_queue を使用して表示した場合でも、メッセージはエンドポイントから取得した優先度レベルを表示しますが、メッセージの転送には既定の優先度レベルが使用されます。

優先度レベルは転送キュー内のメッセージに適用されるため、通常はデータベース エンジンの同じインスタンス内のサービス間で送信されるメッセージに影響を与えません。同じインスタンス内のサービスに送信されるメッセージは、転送キューを経由することなく、そのサービスのキューに直接配置されます。ある種のエラーが発生したり、発信先キューがアクティブでないなどの一部の条件により、ローカル メッセージが転送キューに配置されることがあります。メッセージが転送キューに格納された場合、関連する優先度レベルが適用されます。

メッセージおよびメッセージ フラグメントは、優先度の順序で送信されないことがあります。

  • Service Broker は、メッセージ フラグメントのブロックを使用して、データベース エンジンのインスタンス間でメッセージを送信します。異なる優先度を持つ複数のメッセージ フラグメントが 1 つのインスタンスに送信されるのを待機している場合、Service Broker はすべてのフラグメントを 1 つのブロックで送信することがあります。このブロックの末尾にある一部のフラグメントの優先度は、別のインスタンスへの転送を待機しているメッセージ フラグメントよりも低い場合があります。

  • Service Broker には、多数の優先度の高いメッセージが優先度の低いメッセージをブロックするのを防ぐために、スタベーション防止メカニズムが含まれています。長時間待機している優先度が低いメッセージは、キュー内に優先度が高いメッセージが存在する場合でも、送信することが可能です。

個々のメッセージまたはメッセージ フラグメントが優先度の順序で送信されないことはありますが、送信される多数のメッセージと比較して考えると、その影響は大きくありません。