メッセージ セッション
Azure Service Bus セッションでは、関連メッセージのバインドなしシーケンスの結合および順序指定処理が可能です。 セッションは、先入れ先出し (FIFO) および要求 - 応答のパターンで使用できます。 この記事では、Service Bus の使用時に、セッションを使用してこれらのパターンを実装する方法について説明します。
Note
Service Bus の Basic レベルはセッションをサポートしていません。 Standard レベルと Premium レベルはセッションをサポートしています。 これらのレベルの違いについては、「Service Bus の価格」を参照してください。
先入れ先出し (FIFO) パターン
Service Bus キューまたはサブスクリプションでのメッセージ処理において FIFO 処理を保証するには、セッションを使用します。 Service Bus では、メッセージ間の関係の性質に関する規範はなく、またメッセージのシーケンスの開始位置や終了位置を決定する特定のモデルは定義されていません。
セッションに固有のアプリケーション定義の識別子にセッション ID のプロパティを設定することで、どのセンダーでも、メッセージをトピックまたはキューに送信するときにセッションを作成できます。 AMQP 1.0 プロトコル レベルでは、この値は group-id プロパティに相当します。
セッション対応のキューまたはサブスクリプションでは、セッション ID を持つメッセージが 1 つ以上ある場合にセッションが生成されます。 1 度生成されたセッションの有効期限や存続期間、および API は定義されていません。 理論上は、メッセージを今日のセッションで受信して、次のメッセージを 1 年後に受信したとしても、セッション ID が一致する限り、Service Bus の観点からすると同じセッションになります。
通常、アプリケーションでは関連するメッセージの開始および終了は明確に認識されます。 Service Bus では、特定の規則は設定されていません。 たとえば、アプリケーションでは、最初のメッセージの Label プロパティを start に、中間メッセージの場合であれば content に、最後のメッセージであれば end に設定できます。 コンテンツ メッセージの相対位置は、現在のメッセージの SequenceNumber と start メッセージの SequenceNumber との差分として計算できます。
重要
キューまたはサブスクリプションでセッションが有効になっている場合、クライアント アプリケーションでは通常のメッセージを送受信 "できなくなります"。 すべてのメッセージは、(セッション ID を設定して) セッションの一部として送信し、セッションを受信することで受信する必要があります。 クライアントは、セッションが有効になっているキューまたはサブスクリプションをまだクイック表示できます。 「メッセージの読み取り」を参照してください。
セッションに対応する API は、キューまたはサブスクリプション クライアントに存在します。 セッションやメッセージの受信タイミングを制御する命令モデルと、受信ループ管理の複雑さを隠すハンドラー ベースのモデルがあります。
サンプルについては、「次のステップ」セクションにあるリンクを使用してください。
セッションの機能
セッションは、順序指定の送信を維持し保証しながら、インターリーブされたメッセージ ストリームの同時逆多重化を提供します。
セッション受信プロセスは、セッションを受け入れるクライアントによって作成されます。 セッションがクライアントによって受け入れられて保持されると、クライアントではキューまたはサブスクリプションでそのセッションのセッション ID を持つすべてのメッセージに対する排他ロックが保持されます。 後で到着するセッション ID を持つすべてのメッセージに対しても排他ロックが保持されます。
このロックは、受信側で close メソッドが呼び出されるか、ロックの有効期限が切れた場合に解放されます。 受信側には、ロックを更新するためのメソッドもあります。 その代わりに、ロックの更新を続ける期間を指定できる、ロックの自動更新機能を使用できます。 セッション ロックは、ファイルの排他的ロックと同様に処理する必要があります。つまり、アプリケーションは、セッションが不要になったり、それ以上のメッセージが想定されなくなったりしたらただちにセッションを閉じる必要があります。
複数の同時受信プロセスがキューからプルする場合、特定のセッションに属するメッセージは、そのセッションに対するロックを現在保持している特定の受信プロセスに送信されます。 この操作により、1 つのキューまたはサブスクリプション内のインターリーブされたメッセージ ストリームはさまざまな受信プロセスに対してクリーンに逆多重化されます。また、ロック管理が Service Bus 内のサーバー側で行われるため、それらの受信プロセスはさまざまなクライアント マシン上に存続できます。
上の図には、3 つの同時セッション受信プロセスが示されています。 SessionId
= 4 の 1 つのセッションには有効な所有クライアントがなく、メッセージはこの特定のセッションから配信されません。 セッションは、サブ キューなどのさまざまな方法で機能します。
セッション受信プロセスによって保持されるセッション ロックは、peek-lock 解決モデルによって使用されるメッセージ ロックの傘です。 セッションに対してロックを保持できるのは、1 つの受信プロセスだけです。 受信プロセスは多数のインフライト メッセージを受け取る可能性がありますが、メッセージは順番に受信されます。 メッセージを破棄すると、同じメッセージが、次の受信操作で再利用されます。
メッセージ セッションの状態
ワークフローが大規模で高可用性のクラウド システムで処理される場合、特定のセッションに関連付けられている、ワークフロー ハンドラーは、想定外の障害から回復でき、異なるプロセスやマシンで部分的に完了した作業をその作業が開始した場所から再開できる必要があります。
セッション状態機能は、そのセッションに対して記録された処理の状態になるようにすぐに利用可能なセッションが、新しいプロセッサによって取得されるときに、ブローカー内のメッセージ セッションのアプリケーションで定義された注釈を使用できます。
Service Bus の観点からは、メッセージ セッションの状態は、Service Bus Standard の場合は 256 KB の、Service Bus Premium の場合は 100 MB のサイズのデータを保持できる不透明なバイナリ オブジェクトです。 セッションに対する処理状態は、セッション状態に保持されるか、セッション状態は記憶域の場所または情報が保管されているデータベース レコードを指すことができます。
セッション状態を管理するためのメソッド、SetState
と GetState
はセッション受信プロセスのオブジェクトにあります。 過去にセッション状態がなかったセッションは、GetState
への参照として null を返します。 以前に設定したセッション状態をクリアするには、受信側の SetState
メソッドに null を渡します。
セッション状態は、セッション内のすべてのメッセージが処理されても、クリア (null を返す) されない限りそのままです。
キューに保持されたセッション状態またはサブスクリプション数は、そのエンティティのストレージ クォータがいっぱいになるまで計算されます。 このため、セッションでアプリケーションが終了したら、外部管理コストを回避するために、アプリケーションで保持された状態をクリーンアップすることを推奨します。
配信数の影響
メッセージごとの配信数の定義は、セッションのコンテキストと、セッションがない場合とで若干異なります。 配信数が増える場合についてまとめた表を次に示します。
シナリオ | メッセージの配信数が増える |
---|---|
セッションは受け入れられますが、(タイムアウトによって) セッション ロックの有効期限が切れています | はい |
セッションは受け入れられ、セッション内のメッセージは (ロックされている場合でも) 完了しておらず、セッションは閉じられています | いいえ |
セッションは受け入れられ、メッセージが完了した後、セッションは明示的に閉じられています | 該当なし (これは標準のフローです。この場合、メッセージはセッションから削除されます) |
要求 - 応答パターン
要求 - 応答パターンは、適切に確立された統合パターンであり、送信側アプリケーションから要求を送信でき、受信側が送信側アプリケーションに応答を正しく送信する手段を提供します。 このパターンには、通常、アプリケーションからの応答の送信先となる、有効期間が短いキューまたはトピックが必要です。 このシナリオでは、セッションは、同等のセマンティクスを持つ単純な代替ソリューションを提供します。
送信側アプリケーションを一意に識別するように特定のヘッダー パラメーターを設定することにより、複数のアプリケーションが 1 つの要求キューに要求を送信できます。 受信側アプリケーションは、キューに入ってくる要求を処理し、セッション対応のキューで応答を送信して、送信側が要求メッセージで送信した一意識別子にセッション ID を設定します。 要求を送信したアプリケーションは、特定のセッション ID でメッセージを受信し、応答を正しく処理することができます。
注意
最初の要求を送信するアプリケーションでは、セッション ID を認識し、それを使用して、応答を期待しているセッションがロックされるようにする必要があります。 アプリケーションのインスタンスをセッション ID として一意に識別する、GUID を使用することをお勧めします。特定の受信プロセスが応答をロックして処理できるようにするには、キューのセッション受信プロセスにセッション ハンドラーまたはタイムアウトを指定しないでください。
シーケンスとセッション
シーケンス番号自体はメッセージのキュー順序と抽出順序を保証しますが、セッションを必要とする処理順序は保証しません。
たとえば、キューに 3 つのメッセージがあり、2 つのコンシューマーがあるとします。
- コンシューマー 1 がメッセージ 1 を取得します。
- コンシューマー 2 がメッセージ 2 を取得します。
- コンシューマー 2 はメッセージ 2 の処理を終了し、メッセージ 3 を取得しますが、コンシューマー 1 はまだメッセージ 1 の処理を終了していません。
- コンシューマー 2 がメッセージ 3 の処理を終了しますが、コンシューマー 1 はまだメッセージ 1 の処理を終了していません。
- 最後に、コンシューマー 1 がメッセージ 1 の処理を完了します。
この場合、メッセージの処理は、メッセージ 2、メッセージ 3、メッセージ 1 の順に行われます。 メッセージ 1、2、3 を順番に処理する必要がある場合は、セッションを使用する必要があります。
メッセージを順番に取得するだけでよい場合は、セッションを使用する必要はありません。 メッセージを順番に処理する必要がある場合は、セッションを使用します。 同類のメッセージには同じセッション ID を設定する必要があります。たとえば、あるセットのメッセージ 1、4、8 と、別のセットの 2、3、6 のようになります。
メッセージの有効期限
セッションが有効なキューまたはトピックのサブスクリプションの場合、メッセージはセッション レベルでロックされます。 いずれかのメッセージの有効期限 (TTL) が期限切れになった場合、そのセッションに関連するすべてのメッセージは、エンティティのメッセージングの有効期限設定で有効になっている配信不能機能に基づいて、破棄されるか、配信不能になります。 つまり、セッション内に TTL を過ぎたメッセージが 1 つある場合、セッション内のすべてのメッセージが期限切れになります。 メッセージは、アクティブなリスナーがある場合にのみ期限切れになります。 詳しくは、メッセージの有効期限に関する記事をご覧ください。
次のステップ
メッセージ セッションは、Azure portal、PowerShell、CLI、Resource Manager テンプレート、.NET、Java、Python、JavaScript を使用して、キューの作成中に有効にすることができます。 詳細については、メッセージ セッションの有効化に関するページを参照してください。
Azure Service Bus の機能については、使用する言語のサンプルを試してみてください。
- .NET
- Java
- Python
- JavaScript