共用方式為


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

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

本文說明服務匯流排中的無效信件佇列。 大部分的討論內容是以 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 命令,以取得 DLQ 訊息的計數:az servicebus topic subscription show

將訊息移至 DLQ

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

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

存留時間

當您在佇列或訂閱上啟用無效信件時,所有過期的訊息都會移至 DLQ。 無效信件原因代碼會設定為:TTLExpiredException。 延遲的訊息將不會在過期之後清除並移至無效信件佇列。 這是依照設計的行為。

最大傳遞計數

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

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

如果您在篩選評估例外狀況上啟用了無效信件,訂閱的 SQL 篩選規則在執行時所發生的任何錯誤,會連同違規訊息一起擷取在 DLQ 中。 請勿在生產環境中使用此選項,其中訊息類型會傳送至沒有訂閱者的主題,因為這可能會造成大量的 DLQ 訊息負載。 因此,請確定傳送至主題的所有訊息至少有一個相符的訂用帳戶。

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

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

在 .NET 中,可以呼叫 ServiceBusReceiver.DeadLetterMessageAsync 方法來完成此動作。

建議您在 DeadLetterReason 中包含例外狀況的類型,以及在 DeadLetterDescription 中包含例外狀況的堆疊追蹤,因為這可讓您更輕鬆地針對導致訊息成為無效信件的問題原因進行疑難排解。 請注意,這可能會導致某些訊息超過 Azure 服務匯流排標準層的 256 KB 配額限制。 您可以將服務匯流排命名空間從標準層升級至進階層,以擁有較高的配額和限制

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

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

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

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

  • 如果目的地佇列或主題已停用,訊息會傳送至來源佇列的傳送無效信件佇列 (TDLQ)。
  • 如果目的地佇列或實體超過實體大小,訊息會傳送至來源佇列的 TDLQ。

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

解決導致訊息寄不出的信件問題之後,您可以將它重新提交至佇列或主題以重新處理。

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

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