【Azure Service Bus】 Service Bus如何確保消息發送成功,發送端是否有Ack機制 


問題描述

Service Bus如何確保消息發送成功,發送端是否有Ack機制(是否有回調API告訴發送端,服務端已經收到消息)?根據對.NET發送Service Bus消息代碼的分析,發送方法queueClient.SendAsync(message)並沒有返回值,所以無法知道發送消息是否成功。

 

 

問題根源

Azure 服務總線已針對持久性進行優化,會確保在服務確認請求成功之前,發送到服務總線的所有數據將提交到存儲。一旦服務總線成功“ACK”(確認)請求,即表示服務總線已成功處理該請求。 如果服務總線返回“NACK”(失敗),則表示服務總線無法處理該請求,客戶端應用程序必須重試該請求。官方提供的SDK,在沒有自定義RetryPolicy的情況下,都會采用默認的重試機制。

 

Service Bus .Net SDK 默認的重試機制(RetryPolicy)為:

  • DeltaBackoff: 重試之間的間隔時間
  • MaxRetryCount: 最大重試次數
  • MaximumBackoff: 最大的間隔時間
  • MinimalBackoff: 最小的間隔時間

 

所以在調用Service Bus SDK發送消息時,如果代碼正常執行且沒有Exception,則表示消息成功發送。

 

一句話總結為:無錯即成功,失敗看異常。

 

另外也有如下兩種發送倆查看消息:

方式一:在Azure Service Bus門戶中查看指標 Incoming request/message

 

 

方式二:通過Servie Bus Explorer工具查看發送消息的內容

 

Service Bus異常消息類型

  1. 用戶代碼錯誤(System.ArgumentExceptionSystem.InvalidOperationExceptionSystem.OperationCanceledExceptionSystem.Runtime.Serialization.SerializationException)。 常規操作:繼續之前嘗試修復代碼。
  2. 設置/配置錯誤(Microsoft.ServiceBus.Messaging.MessagingEntityNotFoundExceptionSystem.UnauthorizedAccessException)。 常規操作:檢查配置,必要時進行更改。
  3. 暫時性異常(Microsoft.ServiceBus.Messaging.MessagingExceptionMicrosoft.ServiceBus.Messaging.ServerBusyExceptionMicrosoft.ServiceBus.Messaging.MessagingCommunicationException)。 常規操作:重試操作或通知用戶。 客戶端 SDK 中的 RetryPolicy 類可以配置為自動處理重試。 有關詳細信息,請參閱重試指南
  4. 其他異常(System.Transactions.TransactionExceptionSystem.TimeoutExceptionMicrosoft.ServiceBus.Messaging.MessageLockLostExceptionMicrosoft.ServiceBus.Messaging.SessionLockLostException)。 常規操作:特定於異常類型。

 

異常類型

下表列出了消息異常的類型及其原因,並說明可以采取的建議性操作。


異常類型
異常類型 說明/原因/示例 建議的操作 自動/立即重試注意事項
TimeoutException 服務器在 OperationTimeout 控制的指定時間內未響應請求的操作。 服務器可能已完成請求的操作。 這可能是由於網絡或其他基礎結構延遲造成的。 檢查系統狀態的一致性,並根據需要重試。 請參閱超時異常 在某些情況下,重試可能會有幫助;在代碼中添加重試邏輯。
InvalidOperationException 不允許在服務器或服務中執行請求的用戶操作。 有關詳細信息,請查看異常消息。 例如,如果在 ReceiveAndDelete 模式下收到消息,則 Complete() 將生成此異常。 檢查代碼和文檔。 確保請求的操作有效。 重試不起作用。
OperationCanceledException 嘗試對已關閉、中止或釋放的對象調用某個操作。 在極少數情況下,環境事務已釋放。 檢查代碼並確保代碼不會對已釋放的對象調用操作。 重試不起作用。
UnauthorizedAccessException TokenProvider 對象無法獲取令牌,該令牌無效,或者令牌不包含執行操作所需的聲明。 確保使用正確的值創建令牌提供程序。 檢查訪問控制服務的配置。 在某些情況下,重試可能會有幫助;在代碼中添加重試邏輯。
ArgumentException
ArgumentNullException
ArgumentOutOfRangeException
提供給該方法的一個或多個參數均無效。
提供給 NamespaceManager 或 Create 的 URI 包含路徑段。
提供給 NamespaceManager 或 Create 的 URI 方案無效。
屬性值大於 32 KB。
檢查調用代碼並確保參數正確。 重試不起作用。
MessagingEntityNotFoundException 與操作關聯的實體不存在或已被刪除。 確保該實體存在。 重試不起作用。
MessageNotFoundException 嘗試接收具有特定序列號的消息。 找不到此消息。 確保該消息尚未接收。 檢查死信隊列,以確定該消息是否被視為死信。 重試不起作用。
MessagingCommunicationException 客戶端無法與服務總線建立連接。 確保提供的主機名正確並且主機可訪問。

如果你的代碼在使用防火牆/代理的環境中運行,請確保到服務總線域/IP 地址和端口的流量未被阻止。

如果存在間歇性的連接問題,重試可能會有幫助。
ServerBusyException 服務目前無法處理請求。 客戶端可以等待一段時間,並重試操作。 客戶端可在特定的時間間隔后重試操作。 如果重試導致其他異常,請檢查該異常的重試行為。
MessagingException 在以下情況下,可能會引發一般消息異常:

嘗試使用屬於其他實體類型(例如主題)的名稱或路徑創建 QueueClient

嘗試發送大於 256 KB 的消息。

服務器或服務在處理請求期間遇到錯誤。 有關詳細信息,請查看異常消息。 這通常是暫時性異常。

 

由於實體正受到限制,因此已終止請求。 錯誤代碼:50001、50002、50008。

檢查代碼,並確保只對消息正文使用可序列化對象(或使用自定義序列化程序)。

在文檔中查看屬性支持的值類型,並只使用支持的類型。

檢查 IsTransient 屬性。 如果為 true,可以重試操作。

如果異常是由於限制導致的,請等待幾秒鍾,然后重試該操作。 重試行為未定義,在其他場景中可能沒有幫助。
MessagingEntityAlreadyExistsException 嘗試使用已被該服務命名空間中另一實體使用的名稱創建實體。 刪除現有的實體,或者選擇不同的名稱來創建實體。 重試不起作用。
QuotaExceededException 消息實體已達到其允許的最大大小,或已超出到命名空間的最大連接數。 通過從實體或其子隊列接收消息在該實體中創建空間。 請參閱QuotaExceededException 如果同時已刪除消息,則重試可能會有幫助。
RuleActionException 如果嘗試創建無效的規則操作,服務總線將返回此異常。 如果在處理該消息的規則操作時出錯,服務總線會將此異常附加到死信消息。 檢查規則操作是否正確。 重試不起作用。
FilterException 如果嘗試創建無效的篩選器,服務總線將返回此異常。 如果在處理該消息的篩選器時出錯,服務總線會將此異常附加到死信消息。 檢查篩選器是否正確。 重試不起作用。
SessionCannotBeLockedException 嘗試接受具有特定會話 ID 的會話,但該會話當前已被另一客戶端鎖定。 確保該會話未由其他客戶端鎖定。 如果在此期間會話已釋放,則重試可能會有幫助。
TransactionSizeExceededException 事務包含過多的操作。 減少此事務中操作的數目。 重試不起作用。
MessagingEntityDisabledException 對已禁用的實體請求運行時操作。 激活實體。 如果在此期間該實體已激活,則重試可能會有幫助。
NoMatchingSubscriptionException 如果向已啟用預篩選的主題發送消息並且所有篩選器都不匹配,則服務總線返回此異常。 確保至少有一個篩選器匹配。 重試不起作用。
MessageSizeExceededException 消息有效負載超出 256 KB 限制。 256-KB 限制是指總消息大小,可能包括系統屬性和任何 .NET 開銷。 減少消息負載的大小,並重試操作。 重試不起作用。
TransactionException 環境事務 (Transaction.Current) 無效。 該事務可能已完成或已中止。 內部異常可能提供了更多信息。   重試不起作用。
TransactionInDoubtException 已對未決事務嘗試進行操作,或嘗試提交該事務並且事務進入不確定狀態。 應用程序必須處理此異常(作為特例),因為此事務可能已提交。

參考資料

Service Bus Explorer: https://github.com/paolosalvatori/ServiceBusExplorer/releases

Service Bus Retry Policy: https://docs.microsoft.com/en-us/azure/architecture/best-practices/retry-service-specific#service-bus

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM