Service Broker 通信プロトコル

Service Broker は、ブローカ固有のプロトコルを使用してリモート ブローカと通信します。ブローカは、クライアント接続の通常のプールとは別に接続を管理します。2 つの SQL Server インスタンス間で Service Broker メッセージを交換するには、どちらのインスタンスも、相手のインスタンスが Service Broker 通信に使用しているポートに TCP/IP トラフィックを送信できる必要があります。慣例により、Service Broker は、ブローカ間通信にポート 4022 を使用することがよくあります。ただし、正確なポートは、エンドポイントを作成する際に指定します。

プロトコル レイヤ

Service Broker では、レイヤ化されたアプローチを通信に採用しています。各レイヤは、基礎となるレイヤの上に構成され、それによって信頼性の高い配信を行うことができます。このアプローチにより、アプリケーションは、リモート サービスの場所や、ブローカが通信に使用する物理トランスポートに関する情報なしで動作できます。ほとんどの場合、これらのプロトコルは、アプリケーションに対して透過的です。しかし、各プロトコル レイヤの役割を理解しておくことは、アプリケーションに関する問題をトラブルシューティングする際に役立つ場合があります。

ブローカが使用する最上位プロトコルは、ダイアログ プロトコルです。ダイアログ プロトコル レイヤは、信頼性の高い、シーケンス付きメッセージ転送を処理します。ダイアログ プロトコル レイヤは、メッセージのシーケンス番号を生成し、受信確認メッセージを生成し、メッセージを正しいキューに配信し、メッセージをフラグメント化および再組み立てします。ダイアログ プロトコルは、ダイアログの認証および暗号化を処理します。

ダイアログ プロトコルは、メッセージ フラグメントを転送するために、隣接するブローカ プロトコルを使用します。隣接するブローカ プロトコルは、2 つのブローカ インスタンス間で交換されるネットワーク転送を処理します。

隣接するブローカ プロトコルは、メッセージをブローカ間で移動する際に、TCP/IP などのトランスポート プロトコルを使用します。

ダイアログ プロトコル

ダイアログ プロトコルは、メッセージ交換の、EOIO (exactly-once-in-order) メッセージ配信パターンを管理します。このプロトコルでは、Service Broker メッセージがネットワーク上で使用する形式を記述しません。その代わりに、このプロトコルは、信頼性の高いメッセージ交換に必要な論理的ステップを指定します。ダイアログ プロトコルは、受信確認メッセージの生成および処理を含め、信頼性の高い配信に必要なタスクを処理します。

メッセージ交換の両側は、ダイアログ プロトコル レイヤのエンドポイントです。カタログ ビュー sys.conversation_endpoints には、ダイアログ プロトコル エンドポイントに関する情報が表示されます。メッセージ交換のエンドポイントは、メッセージ交換の有効期間が終わるまで存在します。

隣接するブローカ プロトコル

隣接するブローカ プロトコル レイヤは、2 つの SQL Server インスタンス間の通信機構を処理します。このレイヤは、各メッセージ フラグメントを、ネットワーク経由での転送に適した標準のフォーマットにエンコードします。ダイアログ プロトコル レイヤとは異なり、隣接するプロトコル レイヤは、使用されるネットワーク トランスポートを認識し、メッセージ フラグメントを適切にフォーマットします。実際には、隣接するブローカ プロトコル レイヤは、ダイアログ プロトコル レイヤとトランスポート プロトコル レイヤの間の抽象化レイヤを提供します。

各 Service Broker ネットワーク接続は、隣接するプロトコル レイヤのエンドポイントです。動的管理ビュー sys.dm_broker_connections には、Service Broker ネットワーク接続に関する情報が表示されます。Service Broker は、メッセージが交換されている間、ネットワーク接続を維持します。Service Broker は、短時間でもネットワーク接続経由で送受信されるメッセージがないと、ネットワーク接続を閉じます。

トランスポート プロトコル

トランスポート プロトコル レイヤは、実際のネットワーク転送を処理します。このレイヤは Service Broker 外です。たとえば、SQL Server の別のインスタンスで実行されているブローカへのメッセージには、トランスポート プロトコル レイヤとして TCP/IP が使用されます。

Service Broker エンドポイントは、トランスポート プロトコルのオプションを設定します。SQL Server は、既定では Service Broker エンドポイントを含みません。Service Broker エンドポイントを作成する方法の詳細については、「Service Broker ネットワークをアクティブ化する方法 (Transact-SQL)」を参照してください。

Service Broker のメッセージ処理

Service Broker では、異なる 2 種類のメッセージが使用されます。シーケンス付きメッセージは、アプリケーションに正しい順序で一度だけ配信される必要のあるメッセージです。シーケンスが付けられていないメッセージは、メッセージが着信した順序に関係なく、直ちに処理することのできるメッセージです。

Service Broker は、すべてのユーザー定義メッセージ型、終了ダイアログ メッセージ、およびアプリケーションが生成したエラー メッセージに対して、シーケンス付きメッセージを使用します。各シーケンス付きメッセージは、シーケンス番号を持っています。メッセージを送信するインスタンスは、メッセージ シーケンス番号を生成し、そのシーケンス番号をメッセージに割り当てます。受信側のブローカは、そのメッセージ シーケンス番号を使用して、アプリケーションに渡すメッセージを配列します。1 つのダイアログ内では、アプリケーションは常にシーケンス番号が最も小さいメッセージを最初に受け取ります。Service Broker は、重複したメッセージを検出する際にも、メッセージ シーケンス番号を使用します。ダイアログ プロトコル レイヤが、同じシーケンス番号の、同じダイアログに関する 2 つのメッセージを受信した場合、ダイアログ プロトコル レイヤはメッセージが重複しているものと見なし、一方を破棄します。

Service Broker は、専用の受信確認メッセージ、および Service Broker が生成したエラー メッセージに対して、シーケンスが付けられていないメッセージを使用します。Service Broker は、シーケンスが付けられていないメッセージを配信する際に、特別な対策は行いません。ただし、シーケンスが付けられていないメッセージは、着信メッセージに対する応答として Service Broker によって生成されることに注意してください。そのため、シーケンスが付けられていないメッセージが失われると、送信側は元のメッセージの送信を再試行します。その場合、受信側はシーケンスが付けられていないメッセージを再び生成します。

メッセージのフラグメント化

Service Broker では、送信するメッセージをフラグメントに分割し、着信したフラグメントを結合して元のメッセージにします。サイズの小さなメッセージの場合は、そのメッセージ全体が 1 つのフラグメントに含まれます。サイズの大きなメッセージの場合は、Service Broker によって多数のフラグメントが作成されます。

メッセージをフラグメント化することには、いくつかの利点があります。サイズの大きなメッセージを小さなフラグメントに分割して送信すると、ワイドエリア ネットワーク (WAN) などの比較的低速で信頼性の低いネットワーク経由で通信する場合に、全体的な速度と信頼性が向上します。メッセージを構成するフラグメントの 1 つが失われた場合には、メッセージ全体ではなく、1 つのフラグメントのみが再転送されます。サイズの大きなメッセージをフラグメント化することで、サイズの小さなメッセージが転送先に到達するための所要時間を短縮することもできます。Service Broker は、サイズの小さなメッセージ全体を格納した 1 つのフラグメントを、サイズの大きなメッセージの複数のフラグメント間に送信できます。この場合、サイズの小さなメッセージが転送を待機する時間を短縮するため、サイズの大きなメッセージの転送速度がわずかに遅くなります。

メッセージが再構築されている間、メッセージの断片は、転送先のキューに格納されます。転送先のキューが利用できない場合は、転送キューに格納されます。メッセージの断片は、アプリケーションでは受信できません。メッセージの断片の status 列は、2 (無効) に設定されます。この値は、間違った順番で受信されたメッセージにも使用されます。

メッセージ受信確認

Service Broker は、受信した各メッセージに対して受信確認を行います。受信確認は、1 つまたは複数のメッセージ フラグメントを確認することができます。可能な場合には、受信確認は、同じメッセージ交換で返送されるメッセージのヘッダーに組み込まれます。送信できるメッセージがない場合、Service Broker は専用の受信確認メッセージを返送します。メッセージ受信確認は、すべて Service Broker によって処理されます。Service Broker を使用するアプリケーションは、これらのメッセージを受信しません。

送信側は、受信側が受信確認していないメッセージ フラグメントを保持します。システム定義の待機時間内に受信確認が受信されない場合には、送信側はそのメッセージ フラグメントを再送信します。待機時間内に受信確認が受信されない場合、Service Broker では、次の再試行までの待機時間を、最大待機時間に達するまで幾何級数的に増加させながら、再試行を繰り返します。再試行までの最初の待機時間は数秒間です。最大待機時間は、およそ 1 分間です。待機時間は正確なものではないことに注意してください。ネットワーク トラフィックや、SQL Server インスタンスのその他のアクティビティによって、待機時間終了後、数秒間にわたってメッセージ フラグメントの再送信が再試行されない場合もあります。

受信確認が失われたり、遅延したりした場合、受信側はメッセージを重複して受信する場合があります。この場合、受信側は重複したメッセージの受信に対して受信確認を行いますが、重複したメッセージをキューに配信することはありません。

Service Broker では、メッセージ受信確認を、分散トランザクションを使用せずに信頼性の高いメッセージを提供するために使用します。受信側は、メッセージまたはメッセージ フラグメントをキューに追加した後でのみ、受信確認を送信します。送信側は、メッセージの受信確認が到着するまで、そのメッセージを転送キュー内に保持します。送信側と受信側がトランザクションを共有することはありませんが、このプロトコルでは、受信側がメッセージを正常に受信するまで、送信側が転送キューからメッセージを削除しないことが保証されます。

メッセージの整合性チェック

Service Broker がメッセージの転送に使用するフォーマットには、メッセージが転送中に変更されたり、破損したりしていないかどうかを判別するために、メッセージの整合性チェックが含まれています。

メッセージの整合性チェックには、メッセージの内容に関する MD5 署名が使用されます。SQL Server は、メッセージのセッション キーを使用して署名を暗号化し、その署名をメッセージ ヘッダーに組み入れます。

メッセージの転送先は、メッセージの暗号化を解除し、メッセージ内の署名を、受信した実際の内容から計算した新しい署名と比較します。2 つの署名が一致しない場合、そのメッセージは転送中に破損したか、または改ざんされていることになります。このメッセージは、メッセージの整合性チェックに失敗します。SQL Server はそのメッセージを破棄し、送信側に対してそのメッセージに関する受信確認を行いません。メッセージがメッセージの整合性チェックに失敗すると、Broker:Corrupted Message イベント クラスが情報を報告します。

Service Broker 転送オブジェクト

Service Broker 転送オブジェクトとは、ダイアログのメッセージ転送状態を管理および記録する、メモリ内オブジェクトです。メッセージ交換エンドポイントごとに 1 つの転送オブジェクトがあります。

ダイアログが転送オブジェクトを要求するのは、次のような場合です。

  • 転送キュー経由でメッセージを送信する場合。これには次のメッセージが含まれます。

    • データベース エンジンのリモート インスタンスに送信されたすべてのメッセージ

    • メッセージを直接転送先のキューに挿入できない場合に、ローカル インスタンス内のキューに送信されたメッセージ

  • リモート メッセージ、またはローカルの転送キューからのメッセージを受信する場合。

転送オブジェクトは、最初にダイアログによって要求されたときに作成されます。Service Broker では、そのダイアログからの以降の要求に同じ転送オブジェクトを使用します。転送オブジェクトは、Service Broker がダイアログの転送状態の変化を記録する必要が生じるたびに変更されます。転送オブジェクトは約 1 KB です。

メモリを解放するために、Service Broker は非アクティブな転送オブジェクトのバッチを定期的に tempdb の作業テーブルに格納します。転送オブジェクトは、メモリ内で初めて変更されたときに、ダーティとマークされます。転送オブジェクトは、作業テーブルにフラッシュされるまで、ダーティとマークされたままになります。

転送オブジェクトは、直接転送先のキューに挿入できるローカル メッセージの送受信には使用されません。

ネットワーク通信フロー

次の図に、2 つの SQL Server インスタンス間で行われる Service Broker ネットワーク通信の概要を示します。

2 つのインスタンス間でのブローカ ネットワーク通信

メッセージ交換は、永続的な論理的接続であることに注意してください。メッセージ交換は、任意の期間にわたって行われ、その期間内に、任意の数のネットワーク接続を使用します。

ネットワーク接続は、2 つの Service Broker エンドポイント間で行われます。これらの接続では、TCP/IP が使用されます。接続が短期間でも非アクティブになると、SQL Server はネットワーク接続を閉じます。

メッセージを配信するために、Service Broker は、メッセージを送信したデータベースの転送キューにそのメッセージを保持します。受信側は、転送先サービスのキューに、メッセージを直接配信します。そのキューが OFF の場合、メッセージは一時的に、受信側データベースの転送キューに保持されます。送信側サービスのキューは操作に関係しません。受信側サービスをホストするデータベースの転送キューは、転送先キューが OFF の場合にのみ関係します。