Service Broker の利点

Service Broker の機能は、データベース アプリケーションに対して重要な利点を多数提供します。これらの機能および利点は次のとおりです。

  • データベース統合により、アプリケーションのパフォーマンスが向上し、管理が簡素化されます。

  • メッセージの順序付けおよび調整により、アプリケーション開発が簡素化されます。

  • アプリケーションの疎結合により、ワークロードの柔軟性が向上します。

  • 関連メッセージのロックにより、アプリケーションの複数のインスタンスが、明示的に同期することなく、同一のキューからのメッセージを処理できます。

  • 自動アクティブ化により、アプリケーションで大量のメッセージを処理できます。

データベース統合

Service Broker の統合デザインにより、アプリケーションのパフォーマンスが向上し、管理が容易になります。

SQL Server と統合されているため、外部の分散トランザクション コーディネータの使用によるオーバーヘッドや複雑さを発生させることなく、トランザクション メッセージングを利用できます。アプリケーションは、1 つ以上のメッセージの受信、これらのメッセージの処理、および返信メッセージの送信を、単一のデータベース トランザクション内で実行します。トランザクションが失敗すると、すべての処理がロールバックされ、処理を再試行できるように受信メッセージがキューに戻されます。アプリケーションがトランザクションをコミットするまで、実行したアクションは有効になりません。アプリケーションは一貫した状態に保たれます。

データ、メッセージ、およびアプリケーション ロジックがすべてデータベースにある場合、アプリケーション管理 (災害復旧、セキュリティ、バックアップなど) が日常のデータベース管理の一部となり、管理者が 3 つまたは 4 つのコンポーネントを別々に管理する必要がなくなるため、管理作業が容易になります。

従来のメッセージング システムでは、メッセージ ストアとデータベースの一貫性が失われる場合があります。たとえば、あるコンポーネントをバックアップから復元する場合、別のコンポーネントも同時に復元する必要があります。そうしないと、メッセージ ストアの情報がデータベースの情報に一致しなくなります。Service Broker では、メッセージとデータが同じデータベースに格納されるため、一貫性が失われることはありません。

データベース統合のもう 1 つの利点として、共通開発環境が挙げられます。アプリケーションのメッセージ処理部分とデータ部分では、同一の SQL Server 言語や Service Broker アプリケーションのツールを使用できます。これにより、データベース プログラミング手法に関する開発者の習熟度をメッセージ ベースのプログラミングに活かすことができます。Service Broker サービスを実装するストアド プロシージャは、Transact-SQL 言語または共通言語ランタイム (CLR) 言語のいずれかで記述できます。データベース外部のプログラムは、Transact-SQL に加えて、ADO.NET などの使い慣れたデータベース プログラミング インターフェイスを使用します。

さらに、データベース統合により、自動リソース管理が可能になります。Service Broker は SQL Server インスタンスのコンテキストで実行されるため、インスタンス内のすべてのデータベースの送信可能メッセージが Service Broker によって監視されます。これにより、各データベースがそれぞれのキューをメンテナンスできるようになり、Service Broker が SQL Server インスタンス全体のリソース使用量を管理できるようになります。

メッセージの順序付けと調整

従来のメッセージング システムでは、順番どおりに到着しないメッセージの順序付けと調整をアプリケーションが実行していました。たとえば、アプリケーション A がメッセージ 1、メッセージ 2、およびメッセージ 3 を送信したときに、メッセージ 2 にエラーが発生して、アプリケーション B がメッセージ 1 とメッセージ 3 のみを受信および確認したとします。アプリケーション A はメッセージ 2 を再送しますが、このときメッセージ 2 はメッセージ 1 とメッセージ 3 の後に到着することになります。以前は、開発者がメッセージの到着順が問題にならないようにアプリケーションを作成するか、またはアプリケーションが正しい順序でメッセージを処理できるように、メッセージ 2 が到着するまでの間、メッセージ 3 を一時的にキャッシュする必要がありました。どちらのソリューションも難解で複雑です。

従来のシステムのもう 1 つの問題点として、重複配信が挙げられます。上記の例では、アプリケーション B がメッセージ 2 を受信したにもかかわらず、アプリケーション A に対する受信確認メッセージが消失した場合、アプリケーション A はメッセージ 2 を再送することになります。これにより、アプリケーション B はメッセージ 2 を 2 回受信することになります。重複メッセージを識別および破棄するか、または悪影響を与えることなく重複メッセージを再処理するためのコードをアプリケーションに記述する必要がありました。これらもまた実装の困難なアプローチでした。

従来のシステムでは、メッセージの調整も処理の難しい問題でした。たとえば、アプリケーションは数百または数千の要求をサービスに送信する場合があります。サービスは要求を並行して処理し、処理が終了すると直ちに応答を返します。要求ごとに処理時間が異なるため、アプリケーションはメッセージ送信時と異なる順序で応答を受信することになります。ただし、応答を正しく処理するためには、アプリケーションが各応答を適切な送信メッセージに関連付ける必要があります。従来のメッセージング システムでは、各アプリケーションがこの関連付けを実行していました。これにより、アプリケーション開発において、余分なコストと複雑さが発生していました。

Service Broker は、メッセージの順序付け、一意の配信、およびメッセージ交換の識別を自動的に処理することにより、これらの問題を解決します。Service Broker の 2 つのエンドポイントでメッセージ交換が確立されると、アプリケーションは各メッセージを送信順に一度だけ受け取ります。アプリケーションは、追加コードを記述することなく、メッセージを正しい順序で一度だけ処理できます。最後に、Service Broker はすべてのメッセージに対して識別子を自動的に付加します。アプリケーションは、特定のメッセージがどのメッセージ交換に属しているかを常に認識できます。

疎結合とワークロードの柔軟性

Service Broker は、発信側アプリケーションと対象アプリケーションの疎結合を提供します。アプリケーションは、メッセージをキューに送信した後、アプリケーション処理を続行できますが、このときアプリケーションは、Service Broker が宛先にメッセージを確実に配信することを前提としています。この疎結合により、スケジュールを柔軟に設定できます。発信側アプリケーションは複数のメッセージを送信でき、複数の対象サービスがこれらのメッセージを並行して処理できます。対象サービスは、現在のワークロードに応じて、それぞれのペースでメッセージを処理します。

また、キューにより、システムは処理をより均等に分散して、サーバーに必要なピーク時の容量を減少できます。これにより、全体のスループットとデータベース アプリケーションのパフォーマンスが向上します。たとえば、多くのデータベース アプリケーションでは、1 日の特定の時間帯にトランザクションが集中し、リソース消費が増大して応答時間に遅延が発生します。Service Broker を使用すると、これらのアプリケーションはビジネス トランザクションのすべての処理をトランザクション受信時に実行する必要がなくなります。代わりに、アプリケーションは Service Broker を使用して、バックグラウンド処理を実行するアプリケーションにトランザクションの情報を送信します。これらのアプリケーションは時間をかけて確実にトランザクションを処理します。一方、メインの受信アプリケーションは新規ビジネス トランザクションの受信を続行します。

送信先がすぐには利用できない場合、メッセージは送信データベースの転送キューに残ります。Service Broker は、メッセージが正常に送信されるか、またはメッセージ交換の有効期間が終了するまで、メッセージの再送信を継続します。これにより、メッセージ交換のある時点で一方のサービスが利用できなくなった場合でも、2 つのサービス間における信頼性の高いメッセージ交換が維持されます。転送キュー内のメッセージはデータベースの一部となります。インスタンスがフェールオーバーまたは再起動した場合でも、Service Broker はこのメッセージを配信します。

関連メッセージのロック

複数のプログラムによる同一キューからの同時読み取りは、従来のメッセージング アプリケーションにおいて、実現が最も困難な処理の 1 つでした。従来のメッセージング システムにおいては、複数のプログラムまたはスレッドが同一のキューから読み取りを実行する場合、メッセージが順不同で処理されることがあります。Service Broker は、メッセージ交換グループのロックを使用して、このような状況が発生するのを防ぐことができます。

従来の注文処理アプリケーションについて考えてみましょう。メッセージ A には注文ヘッダーの作成に関する指示が含まれ、メッセージ B には注文品目の作成に関する指示が含まれます。これらのメッセージはキューで受信されます。これらのメッセージが別々のアプリケーションによってキューから取り出され、同時に処理される場合、注文品目トランザクションのコミットが先に実行される可能性があります。この場合、注文がまだ存在しないため、コミットは失敗します。コミットが失敗すると、トランザクションがロールバックされ、メッセージがキューに戻されて再処理されます。これはリソースの無駄になります。従来、プログラマは、メッセージ A とメッセージ B の情報を 1 つのメッセージに結合することによってこの問題を解決していました。メッセージが 2 つの場合、このアプローチはわかりやすいものですが、数十または数百のメッセージの調整が必要なシステムにとっては拡張性に乏しいアプローチです。

Service Broker は、メッセージ交換グループ内の関連するメッセージ交換を関連付けることによってこの問題を解決します。Service Broker は、同じメッセージ交換グループ内のすべてのメッセージを自動的にロックして、1 つのアプリケーション インスタンスのみがこれらのメッセージを受信および処理できるようにします。一方、アプリケーションのその他のインスタンスは、他のメッセージ交換グループのメッセージのキューからの取り出しおよび処理を続行できます。これにより、アプリケーションに複雑なロック コードを記述することなく、複数のアプリケーション インスタンスによる確実かつ効率的な並行処理を実現できます。

自動アクティブ化

Service Broker の最も効果的な機能の 1 つはアクティブ化です。アクティブ化を使用すると、キューに到着するメッセージの量に合わせてアプリケーションを動的に拡張および縮小できます。Service Broker が提供する機能を使用すると、データベース内部で実行されるプログラム、およびデータベース外部で実行されるプログラムの両方でアクティブ化を利用できます。ただし、Service Broker では、アプリケーションによるアクティブ化の使用は必須ではありません。

Service Broker は、キュー内の利用状況を監視して、使用可能なメッセージを持つすべてのメッセージ交換のメッセージをアプリケーションが受信したかどうか判断します。キュー リーダーで実行する処理がある場合、Service Broker のアクティブ化によって新しくキュー リーダーが開始されます。キュー リーダーで実行する処理があるかどうかを判断するために、Service Broker はキューの利用状況を監視します。キュー リーダーの数が受信トラフィックと一致すると、キューは定期的に次のいずれかの状態に達します。つまり、キューが空の状態か、またはキュー内のすべてのメッセージが他のキュー リーダーによって処理されるメッセージ交換に属している状態です。キューが一定期間この状態に達しない場合、Service Broker はアプリケーションの別のインスタンスをアクティブ化します。

アプリケーションがプログラムをアクティブ化する方法は、そのプログラムがデータベース内部で実行される場合と、データベース外部で実行される場合で異なります。データベース内で実行されるプログラムの場合、Service Broker はキューによって指定されたストアド プロシージャのコピーを開始します。データベース外部で実行されるプログラムの場合、Service Broker はアクティブ化イベントを生成します。プログラムは、このイベントを監視して、別のキュー リーダーがいつ必要になるかを判断します。

Service Broker は、アクティブ化によって開始されたプログラムを停止しません。代わりに、アクティブ化されたアプリケーションは、受信メッセージのない状態が一定期間継続すると、自動的にシャットダウンするように記述されます。このようにデザインされたアプリケーションは、サービスに対するトラフィックの変化に合わせてインスタンス数を動的に増減できます。また、システムがシャットダウンまたは再起動された場合、アプリケーションはシステムの再起動時にキュー内のメッセージの読み取りを自動的に開始します。

従来のメッセージング システムにはこのような機能がないため、特定のキューに対するリソースの過大割り当てまたは過小割り当てが任意の時点において発生する場合が少なくありません。