Service Bus の配信不能キューの概要

Azure Service Bus キューおよびトピック サブスクリプションでは、配信不能キュー (DLQ) と呼ばれるセカンダリ サブキューが提供されます。 配信不能キューを明示的に作成する必要はなく、削除したり、メイン エンティティとは別に管理したりすることはできません。

この記事では、Service Bus の配信不能キューについて説明します。 説明の多くは、GitHub の配信不能キューのサンプルに示されています。

配信不能キュー

配信不能キューの目的は、受信者に配信できないメッセージ、または処理できなかったメッセージを保持することです。 したがって、メッセージを DLQ から取り出して、検査することができます。 ユーザーが問題を修正し、メッセージを再送信できる機能を持つアプリケーションがあります。

API とプロトコルの観点では、DLQ は他のキューとほとんど同じですが、メッセージを再送信できるのは親エンティティの配信不能操作でのみである点が異なります。 また、有効期間は監視されず、DLQ のメッセージを配信不能にすることはできません。 配信不能キューは、ピークロック配信、受信と削除、トランザクション操作などの通常の操作を完全にサポートしています。

DLQ は自動的にクリーンアップされません。 DLQ から明示的に取得し、配信不能メッセージを完了するまで、メッセージは DLQ に残ります。

配信不能キューへのパス

配信不能キューにアクセスするには、次の構文を使用します。

<queue path>/$deadletterqueue
<topic path>/Subscriptions/<subscription path>/$deadletterqueue

.NET では、FormatDeadLetterPath メソッドを使用できます。

QueueClient.FormatDeadLetterPath(queuePath)
SubscriptionClient.FormatDeadLetterPath(topicPath, subscriptionName)

DLQ のメッセージ数

メッセージはトピック レベルにはないため、トピック レベルで配信不能キュー内のメッセージ数を取得することはできません。 送信者がトピックにメッセージを送信すると、メッセージはミリ秒以内にトピックのサブスクリプションに転送されるため、トピック レベルには存在しなくなります。 したがって、トピックのサブスクリプションに関連付けられている DLQ にメッセージが表示されます。 次の例では、Service Bus Explorer で、サブスクリプション "test1" の DLQ に現在 62 件のメッセージがあることが示されています。

配信不能キューの 62 通のメッセージを示す画像。

Azure CLI コマンド az servicebus topic subscription show を使用して、DLQ のメッセージ数を取得することもできます。

DLQ にメッセージを移動する

Service Bus には、メッセージがメッセージング エンジン自体から DLQ にプッシュされる原因となるアクティビティがいくつかあります。 アプリケーションは明示的にメッセージを DLQ に移動することもできます。 次の 2 つのプロパティ (配信不能の理由と説明) は、配信不能メッセージに追加されます。 アプリケーションでは配信不能理由のプロパティに対して独自のコードを定義できますが、システムでは以下の値が設定されます。

配信不能メッセージの理由 配信不能メッセージ エラーの説明
HeaderSizeExceeded このストリームのサイズ クォータが制限を超えました。
TTLExpiredException メッセージの有効期限が切れているため、配信不能です。 詳細については、「Time to live」セクションを参照してください。
[https://login.microsoftonline.com/consumers/](Session ID is null) セッションが有効なエンティティではセッション ID が Null のメッセージは許可されません。
MaxTransferHopCountExceeded キュー間で転送するときに許容される最大ホップ数が制限を超えました。 この値は 4 に設定されています。
MaxDeliveryCountExceeded 最大数の配信試行後、メッセージを使用できませんでした。 詳細については、「最大配信数」セクションを参照してください。

Time to Live

キューまたはサブスクリプションで配信不能を有効にすると、有効期限が切れたすべてのメッセージは DLQ に移動されます。 配信不能理由コードは TTLExpiredException に設定されます。 遅延メッセージは、有効期限が切れても、消去されたり、配信不能キューに移動されたりすることはありません。 この動作は仕様です。

最大配信数

Service Bus のキューとサブスクリプションに対してメッセージの配信を試行できる回数には制限があります。 既定値は 10 です。 メッセージがピーク ロック状態で配信されたが、明示的に破棄されたかロックが期限切れになった場合は、メッセージの配信回数が増えます。 配信回数が上限を超えると、メッセージは DLQ に移動されます。 DLQ のメッセージの配信不能理由は MaxDeliveryCountExceeded に設定されます。 この動作を無効にすることはできませんが、最大配信回数を大きい数に設定することはできます。

サブスクリプション ルールの処理中のエラー

フィルター評価の例外で配信不能を有効にすると、サブスクリプションの SQL フィルター規則の実行中に発生したエラーは、問題のあるメッセージと共に DLQ にキャプチャされます。 大量の DLQ メッセージが生成される可能性があるため、サブスクライバーがいないトピックに送信されるメッセージの種類がある運用環境では、このオプションを使用しないでください。 そのため、トピックに送信されるすべてのメッセージに少なくとも 1 つの一致するサブスクリプションがあることを確認します。

アプリケーション レベルの配信不能処理

システム指定の配信不能処理機能に加え、アプリケーションでは DLQ を使用して許容できないメッセージを明示的に拒否できます。 それらには、何らかのシステムの問題により適切に処理できないメッセージ、誤った形式のペイロードを保持するメッセージ、メッセージ レベルのセキュリティ スキームの使用時に認証に失敗したメッセージなどがあります。

.NET でこれを行うには、ServiceBusReceiver.DeadLetterMessageAsync メソッドを呼び出します。

DeadLetterReason に例外の型を、DeadLetterDescription に例外のスタック トレースを含めることをお勧めします。これにより、メッセージが配信不能になる問題の原因のトラブルシューティングが容易になるからです。 その結果、一部のメッセージが Azure Service Bus の Standard レベルの 256 KB クォータ上限を超える可能性があることに注意してください。 Service Bus 名前空間を Standard レベルから Premium レベルにアップグレードしてクォータと上限を高くすることができます。

自動転送シナリオでの配信不能

メッセージは、以下の条件の下で配信不能キューに送信されます。

  • メッセージが、連結されている 5 つ以上のキューまたはトピックを通過する。
  • 送信先キューまたはトピックが無効または削除されている。
  • 送信先キューまたはトピックがエンティティの最大サイズを超えている。

経由送信シナリオでの配信不能

  • 宛先キューまたはトピックが無効になっている場合、メッセージはソース・キューの転送配信不能キュー (TDLQ) に送信されます。
  • 宛先キューまたはエンティティがエンティティ サイズを超えた場合、メッセージはソース キューの TDLQ に送信されます。

再処理する配信不能メッセージの送信

メッセージが配信不能になる原因となった問題を解決したら、メッセージをキューまたはトピックに再送信して再処理できます。

Azure Service Bus Explorer などのツールを使用すると、キューとトピックの間でメッセージを手動で移動できます。 配信不能キューに移動する必要があるメッセージが多数存在する場合、このようなコードで、それらを一度に移動できます。 オペレーターは多くの場合、どの種類のメッセージが処理に失敗したのか、どのソース キューからのものなのか、どのような理由によるものなのかのトラブルシューティングを行うだけでなく、再処理のためにメッセージのバッチを再送信できるように、ユーザー インターフェイスが用意されていることを望みます。 NServiceBus を使用した ServicePulse などのツールは、これらの機能を提供します。

メッセージの期限切れによる配信不能処理設定のさまざまな構成方法については、キューまたはサブスクリプションの配信不能処理の有効化に関する記事を参照してください。