服務匯流排寄不出的信件佇列的概觀

Azure 服務匯流排佇列和主題訂閱提供次要的子佇列,稱為「無效信件佇列」(DLQ)。 無效信件佇列並不需要明確建立,且無法刪除或在主要實體以外管理。

本文說明服務匯流排中的無效信件佇列。 大部分的討論內容是以 GitHub 上的無效信件佇列範例加以說明。

無效信件佇列

無效信件佇列的目的,是保留無法傳遞至任何收件者的訊息,或是無法加以處理的訊息。 隨後可以從 DLQ 移除訊息並加以檢查。 透過運算子的協助,應用程式可能會更正問題並重新提交訊息、記錄發生錯誤及採取更正動作。

從 API 和通訊協定的觀點而言,DLQ 非常類似任何其他佇列,不同之處在於訊息只會透過父實體的無效信件作業提交。 此外,存留時間並未遵守,而且您無法從 DLQ 讓訊息寄不出去。 寄不出的信件佇列完全支援鎖定傳遞和交易式作業。

DLQ 沒有自動清除。 訊息會保留在 DLQ 中,直到您明確地從 DLQ 擷取訊息並完成無效信件訊息。

DLQ 訊息計數

無法在主題層級獲得無效信件佇列中的訊息計數。 這是因為訊息並不位於主題層級中。 相反地,當傳送者將訊息傳送至主題時,訊息會在毫秒內轉送至訂閱,因此,不會再位於主題層級。 所以,您可以在與該主題的訂閱相關的 DLQ 中查看訊息。 在下列範例中,Service Bus Explorer 顯示顯示訂閱「test1」的 DLQ 中目前有 62 則訊息。

Image showing 62 messages in the dead-letter queue.

您也可以使用 Azure CLI 命令,以取得 DLQ 訊息的計數:az servicebus topic subscription show

將訊息移至 DLQ

服務匯流排中有幾個活動會導致訊息從傳訊引擎本身內部推送至 DLQ。 應用程式也可以明確地將訊息移至 DLQ。 下列兩個屬性 (無效信件原因和無效信件描述) 會新增至無效信件訊息中。 應用程式可以將自己的程式碼定義為無效信件原因屬性,但是系統會設定下列值。

無效信件原因 無效信件錯誤描述
HeaderSizeExceeded 已超過這個串流的大小配額。
TTLExpiredException 訊息已過期,且已停止傳送。 如需詳細資訊,請參閱存留時間一節。
[工作階段 ID] 為 null。 啟用工作階段的實體不允許工作階段識別項為 null 的訊息。
MaxTransferHopCountExceeded 已達到在佇列之間轉送時允許的躍點數目上限。 此值會設定為 4。
MaxDeliveryCountExceeded 嘗試傳遞次數達到上限之後,仍無法使訊息消失。 如需詳細資訊,請參閱傳遞計數上限一節。

最大傳遞計數

嘗試傳遞服務匯流排佇列和訂閱的訊息數目有最大限制。 預設值為 10。 每當在 PeekLock 鎖定下傳遞訊息,但已明確放棄或鎖定已過期時,訊息的上的傳遞計數就會遞增。 當傳遞計數超過限制時,訊息便會移至 DLQ。 位於 DLQ 中訊息的無效信件原因會設定為:MaxDeliveryCountExceeded。 此行為無法停用,但您可以將最大傳遞計數設置為較大的數字。

存留時間

當您在佇列或訂閱上啟用無效信件時,所有過期的訊息都會移至 DLQ。 無效信件原因代碼會設定為:TTLExpiredException

延遲的訊息將不會在過期之後清除並移至無效信件佇列。 這是依照設計的行為。

在處理訂用帳戶規則時發生錯誤

如果您在篩選評估例外狀況上啟用了無效信件,訂閱的 SQL 篩選規則在執行時所發生的任何錯誤,會連同違規訊息一起擷取在 DLQ 中。 請勿在並非所有訊息類型都具有訂閱者的生產環境中使用此選項。

應用程式層級無效信件處理

除了系統提供的無效信件處理功能之外,應用程式可以使用 DLQ 明確拒絕無法接受的訊息。 這些包括由於任何類型的系統問題而無法正確處理的訊息、保存格式不正確之承載的訊息,或在使用某些訊息層級安全性配置時無法進行驗證的訊息。

您可以呼叫 ServiceBusReceiver.DeadLetterMessageAsync 方法來完成此動作。

建議您在 DeadLetterReason 中包含例外狀況的類型,以及在 DeadLetterDescription 中包含例外狀況的堆疊追蹤,因為這可讓您更輕鬆地針對導致訊息成為無效信件的問題原因進行疑難排解。 請注意,這可能會導致某些訊息超過 Azure 服務匯流排標準層的 256 KB 配額限制,進一步指出應該將進階層用於實際執行環境。

自動轉寄案例中的無效信件

訊息會在下列情況下傳送至無效信件佇列:

  • 訊息會通過四個以上鏈結在一起的佇列或主題。
  • 目的地佇列或主題已停用或刪除。
  • 目的地佇列或主題超過最大實體大小。

透過案例傳送中的無效信件

  • 如果目的地佇列或主題已停用,訊息會傳送至來源佇列的傳送無效信件佇列 (TDLQ)。
  • 如果刪除了目的地佇列或主題,則會引發 404 例外狀況。
  • 如果目的地佇列或實體超過實體大小,訊息會傳送至來源佇列的 TDLQ。

無效信件佇列的路徑

您可以使用下列語法來存取無效信件佇列:

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

傳送要重新處理的無效信件訊息

由於最終出現在無效信件佇列的訊息中可能會有重要的商務資料,因此當操作員處理完導致訊息一開始成為無效信件的情況時,最好重新處理這些訊息。

Azure Service Bus Explorer 等工具可讓您在佇列與主題之間手動移動訊息。 如果無效信件佇列中有許多需要移動的訊息,類似這樣的程式碼可以協助一次將其全部移動。 操作員通常更喜歡具有一個使用者介面,讓其可以針對哪些訊息類型無法處理、來自哪個來源佇列和造成的原因進行疑難排解,同時仍能夠以批次方式重新提交要重新處理的訊息。 搭配 NServiceBus 的 ServicePulse 等工具會提供這些功能。

下一步

請參閱啟用佇列或訂閱的無效信件,以瞭解在訊息到期設定上設定無效信件的不同方式。