キューを使用するメッセージベースの配信を選択する
音楽共有アプリケーション用のアーキテクチャを計画中であるとします。 あなたはモバイル アプリから Web API に音楽ファイルが確実にアップロードされるようにしたいと考えています。 次に、アーティストが各自のコレクションに新しい音楽を追加したときに、新しい曲の詳細をアプリに直接配信したいと考えています。 このシナリオは、メッセージ ベースのシステムの使用法として最適であり、Azure ではこの問題に対して次の 2 つのソリューションが提供されています。
- Azure Queue Storage
- Azure Service Bus
Azure Queue Storage とは
Queue Storage は、Azure Storage を使用して、REST ベースの単純なインターフェイスを介して世界中のどこからでも安全にアクセスできる多数のメッセージを格納するサービスです。 キューには数百万のメッセージを含めることができ、それを所有するストレージ アカウントの容量によってのみ制限されます。
Azure Service Bus キューとは
Service Bus は、エンタープライズ アプリケーションを対象とするメッセージ ブローカー システムです。 多くの場合、これらのアプリは複数の通信プロトコルを利用し、さまざまなデータ コントラクトと、より高いセキュリティ要件を持ち、クラウドとオンプレミスの両方のサービスを含むことができます。 Service Bus は、こうしたシナリオに的を絞って設計された専用のメッセージング インフラストラクチャの上に構築されます。
これら両方のサービスは、送信されたメッセージを、ターゲットが受信できるようになるまで保持する "キュー" の概念に基づいています。
Azure Service Bus トピックとは
Azure Service Bus トピックはキューと似ていますが、複数のサブスクライバーが存在できます。 キューではなくトピックにメッセージが送信されると、複数のコンポーネントが作業を行うようトリガーできます。 ユーザーが音楽共有アプリケーションで曲を聴いている場合を考えてみましょう。 モバイル アプリによって "Listened" トピックにメッセージが送信されるとします。 そのトピックには、"UpdateUserListenHistory" のサブスクリプションと、それとは別個の "UpdateArtistsFanList" のサブスクリプションが存在します。 これらの各関数は、メッセージの独自のコピーを受信する別個のコンポーネントによって処理されます。
内部的には、トピックではキューが使用されます。 トピックに投稿すると、メッセージがコピーされ、各サブスクリプションのキューにドロップされます。 キューとは、サブスクリプションを処理するコンポーネントがビジー状態で対応できない場合でも、メッセージのコピーは、"各サブスクリプション ブランチによって" 処理されるまでキュー内に存在し続けるというものです。
キューのメリット
キューのインフラストラクチャではさまざまな高度な機能をサポートでき、次のような点で有用です。
信頼性の向上
キューは、分散アプリケーションによって、宛先コンポーネントへの配信が保留されているメッセージの一時保管場所として使用されます。 ソース コンポーネントでは、メッセージをキューに追加でき、宛先コンポーネントでは、そのメッセージを処理するためにキューの先頭で取得できます。 キューにより、メッセージ交換の信頼性が向上します。それは混み合っているときに、宛先コンポーネント側でメッセージを処理する準備が整うまで、メッセージを待機させることができるからです。
メッセージの配信保証
キュー内の各メッセージを宛先コンポーネントに配信する処理は、通常、キュー システムによって保証されます。 しかし、これらの保証は、次のようにさまざまなアプローチで実現できます。
At-Least-Once 配信:このアプローチでは、キューからメッセージを取得するコンポーネントの少なくとも 1 つへ、各メッセージが配信されることが保証されます。 ただし、特定の状況では、同じメッセージが複数回配信される可能性があります。 たとえば、キューからメッセージを取得する Web アプリのインスタンスが 2 つある場合、通常、各メッセージはこれらのインスタンスの 1 つだけに送信されます。 ただし、一方のインスタンスでメッセージの処理に時間がかかり、タイムアウトになった場合、もう一方のインスタンスにもメッセージが送信される可能性があります。 自分の Web アプリ コードは、この可能性を考慮して設計する必要があります。
At-Most-Once 配信: このアプローチでは、各メッセージの配信は保証されず、確率は低いものの各メッセージが届かない場合もあります。 ただし、At-Least-Once 配信の場合とは異なり、同じメッセージが 2 回配信されることはありません。 これは、"自動重複データ検出" と呼ばれる場合もあります。
先入れ先出し法 (FIFO):ほとんどのメッセージング システムでは、通常、メッセージはキューに入れられたのと同じ順番でキューから出されますが、この配信が保証されているかどうかを検討する必要があります。 分散アプリケーションにおいてメッセージが正確に正しい順序で処理される必要がある場合、FIFO 保証を含むキュー システムを選択する必要があります。
トランザクションのサポート
いくつかのメッセージ グループが密接に関連しているために、グループ内の 1 つのメッセージについて配信が失敗すると、問題が発生する場合があります。
たとえば、e コマース アプリケーションを考えてみます。 ユーザーが購入ボタンを選ぶと、一連のメッセージが生成され、次のようにさまざまな処理を行う宛先に送信される可能性があります。
- 注文の詳細を含むメッセージが、処理センターに送信されます。
- 合計額と支払いの詳細を含むメッセージが、クレジット カード プロセッサに送信されます。
- 領収書情報を含むメッセージがデータベースに送信されて、顧客に対して請求書が生成されます。
この場合、すべてのメッセージが確実に処理されるか、そうでなければ、どのメッセージも処理されないようにする必要があります。 クレジット カード メッセージが配信されずに、すべての注文内容が支払いなしに処理された場合、長くは営業を続けられなくなります。 このような問題は、2 つのメッセージをトランザクションにグループ化することによって回避できます。 メッセージ トランザクションは、データベースの場合と同様に、単一のユニットとして成功または失敗します。 クレジット カード情報のメッセージ配信が失敗した場合は、注文詳細のメッセージ配信も失敗します。
どのサービスを選択すべきか
このアーキテクチャでの通信方法ではメッセージを使用する必要があるということを理解したら、Azure Storage キューと Azure Service Bus のどちらを使用するかを選択する必要があります。 どちらのテクノロジも、コンポーネント間でのメッセージの格納と配信に使用できます。 それぞれの機能セットには少々違いがありますが、解決しようとしている問題に応じて、どちらか、または両方を選択できるということです。
Service Bus キューを使用する場合
- At-Most-Once 配信保証が必要である。
- FIFO 保証が必要である。
- メッセージをトランザクションにグループ化する必要がある。
- キューをポーリングせずにメッセージを受信する必要がある。
- キューにロール ベースのアクセス モデルを提供する必要がある。
- 64 KB を超えるが 100 MB 未満のメッセージを処理する必要がある。 サポートされる最大メッセージ サイズは、Standard レベルで 256 KB、Premium レベルで 100 MB です。
- キュー サイズが 1 TB を超えない。 最大キュー サイズは、Standard レベルで 80 GB、Premium レベルで 1 TB です。
- バッチ メッセージを発行および使用する必要がある。
Service Bus トピックを使用する場合
- Service Bus キューによって提供されるすべての機能が必要であり、それに加えて、それぞれ独自の独立した受信者が存在する複数のサブスクリプションのいずれかにメッセージをルーティングできる、パブリッシュ/サブスクライブ パターンを実装する
Queue Storage は機能があまり豊富ではありませんが、これらのいずれの機能も必要ない場合は、より単純な方法として選択できます。 また、ご利用のアプリに次のいずれかの要件がある場合、これは最良のソリューションです。
Queue Storage を使用する場合
- キューを通ったすべてのメッセージの監査証跡が必要である。
- キュー サイズが 1 TB を超えると予想される。
- キュー内のメッセージ処理の進行状況を追跡する必要がある。
キューは、分散アプリケーションのコンポーネント間で送信されるメッセージ用のシンプルで一時的な保存場所です。 キューを使用すると、メッセージを整理し、予測できない需要急増を適切に対処できます。
簡単にコーディングできるシンプルなキュー システムが必要な場合は、Storage キューを使用します。 より高度なニーズに対しては、Service Bus キューを使用します。 1 つのメッセージに対して複数の宛先が存在するが、キューのような動作が必要な場合は、Service Bus トピックを使用します。