服務匯流排傳訊例外狀況 (.NET)
當服務作業或用戶端發生錯誤時,服務匯流排 .NET 用戶端程式庫會顯示例外狀況。 在可行的情況下,系統會使用標準 .NET 例外狀況類型傳達錯誤資訊, 針對服務匯流排的特定案例,會擲回 ServiceBusException。
服務匯流排用戶端會按照已設定的重試選項,自動重試被視為暫時性的例外狀況。 若應用程式顯示例外狀況,即表示所有重試都未能成功套用,或者例外狀況被視為非暫時性。 如需設定重試選項的詳細資訊,請參閱自訂重試選項 (英文) 範例。
ServiceBusException
例外狀況包含一些內容資訊,可協助您了解錯誤的相關內容及其相對嚴重性。
EntityPath
:識別發生例外狀況的服務匯流排實體 (如有)。IsTransient
:指出是否將例外狀況視為可復原。 若例外狀況被視為暫時性,代表 Azure 服務匯流排已套用相關的重試原則,但所有重試均失敗。Message
:提供發生錯誤和相關內容的描述。StackTrace
:代表呼叫堆疊的即時框架,醒目提示程式碼中發生錯誤的位置。InnerException
:若例外狀況是因服務作業而出現,這通常會是描述錯誤的Microsoft.Azure.Amqp.AmqpException
執行個體,並且會遵循 OASIS 進階訊息佇列通訊協定 (AMQP) 1.0 規格 (英文)。Reason
:提供一組已知的失敗原因,有助於釐清根本原因並將其分類。 這些值的目的是在不適合檢查例外狀況訊息的文字時,允許套用例外狀況篩選和其他邏輯。 以下是幾項關鍵的失敗原因:ServiceTimeout
:表示服務匯流排服務未於預期時間內回應作業要求, 可能是因為暫時性網路問題或服務問題所致。 服務匯流排服務不一定已成功完成要求;狀態未知。 在下一個可用工作階段的內容中,此例外狀況表示實體中沒有可用的解除鎖定工作階段。 這類錯誤是會自動重試的暫時性錯誤。QuotaExceeded
:通常表示單一實體的作用中接收作業過多。 若要避免發生這個錯誤,請減少潛在並行接收的數目。 您可以使用批次接收,嘗試針對每項接收要求接收多個訊息。 如需詳細資訊,請參閱服務匯流排配額 (機器翻譯)。MessageSizeExceeded
:表示訊息大小超過訊息大小上限。 訊息大小包含訊息的本文和所有相關聯的中繼資料。 解決這個錯誤的最佳方法是減少批次傳送的訊息數目,或訊息中包含的本文大小。 由於大小限制可能變更,詳情請參閱服務匯流排配額 (機器翻譯)。MessageLockLost
:表示訊息上的鎖定遺失, 呼叫者應該嘗試再次接收和處理訊息。 此例外狀況僅適用於不使用工作階段的實體。 如果處理時間超過鎖定持續時間,且訊息鎖定未更新,就會發生此錯誤。 此外,當連結因為暫時性網路問題,或連結閒置 10 分鐘後中斷連結,也可能會發生此錯誤。服務匯流排服務會使用具狀態的 AMQP 通訊協定。 由於通訊協定的本質,如果連線用戶端與服務的連結在收到訊息之後,但在確定訊息之前中斷連結,就無法在重新連線連結時確定訊息。 連結可能會因為短期暫時性網路失敗、網路中斷,或由於服務強制執行 10 分鐘閒置逾時而中斷。 遇到需要使用連結的作業時,連結會自動重新連線,也就是確定或接收訊息。 因為這個行為的緣故,即使還沒超過鎖定到期時間,您也可能會遇到
ServiceBusException
與MessageLockLost
或SessionLockLost
的Reason
。SessionLockLost
:表示工作階段上的鎖定已到期, 呼叫者應該嘗試再次接受工作階段。 此例外狀況僅適用於已啟用工作階段的實體。 如果處理時間超過鎖定持續時間,且工作階段鎖定未更新,就會發生此錯誤。 此外,當連結因為暫時性網路問題,或連結閒置 10 分鐘後中斷連結,也可能會發生此錯誤。 服務匯流排服務會使用具狀態的 AMQP 通訊協定。 由於通訊協定的本質,如果連線用戶端與服務的連結在收到訊息之後,但在確定訊息之前中斷連結,就無法在重新連線連結時確定訊息。 連結可能會因為短期暫時性網路失敗、網路中斷,或由於服務強制執行 10 分鐘閒置逾時而中斷。 遇到需要使用連結的作業時,連結會自動重新連線,也就是確定或接收訊息。 因為這個行為的緣故,即使還沒超過鎖定到期時間,您也可能會遇到ServiceBusException
與MessageLockLost
或SessionLockLost
的Reason
。MessageNotFound
:嘗試依照實體中不存在或目前已鎖定訊息的序號接收延遲訊息時,就會顯示此原因。SessionCannotBeLocked
:表示要求的工作階段無法鎖定,因為鎖定已保留在其他地方。 鎖定到期后,即可接受工作階段。GeneralError
:表示服務匯流排服務在處理要求時發生錯誤。 此錯誤通常是因服務升級和重新啟動所致。 這類錯誤是會自動重試的暫時性錯誤。ServiceCommunicationProblem
:表示與服務通訊時發生錯誤。 這個問題的肇因可能是暫時性網路問題或服務問題。 這類錯誤是會自動重試的暫時性錯誤。ServiceBusy
:表示要求已由服務進行節流。 若想深入了解哪些原因會造成要求受到節流,以及如何避免受到節流,請參閱這篇文章 (機器翻譯)。 系統會重試已節流要求,但用戶端程式庫會自動套用 10 秒的輪詢,然後再嘗試使用相同的ServiceBusClient
(或在該用戶端建立的任何子類型) 處理其他要求。 如果實體的鎖定持續時間短於 10 秒,可能會發生問題,因為如有任何未確定的訊息或鎖定工作階段,訊息或工作階段可能會遺失。 由於已節流要求通常能夠重試成功,因此產生的例外狀況會記錄為警告,而非錯誤;具體的警告層級事件來源事件為 43 (RunOperation 發生例外狀況並進行重試)。MessagingEntityAlreadyExists
:表示具有相同名稱的實體存在於相同的命名空間下。MessagingEntityDisabled
:訊息實體遭停用, 請使用入口網站再次啟用實體。MessagingEntityNotFound
:服務匯流排服務找不到服務匯流排資源。
處理 ServiceBusException - 範例
以下範例說明如何處理 ServiceBusException
,並依 Reason
進行篩選。
try
{
// Receive messages using the receiver client
}
catch (ServiceBusException ex) when
(ex.Reason == ServiceBusFailureReason.ServiceTimeout)
{
// Take action based on a service timeout
}
其他常見例外狀況
ArgumentException
:與用戶端互動的指定參數無效時,用戶端會擲回衍生自ArgumentException
的例外狀況。 您可以在Message
中找到該參數和問題本質的相關資訊。InvalidOperationException
:嘗試執行對目前設定無效的作業時會發生。 一般而言,當用戶端未設定為支援特定作業時,會發生此例外狀況。 通常只要調整傳遞至用戶端的選項,便能減輕此例外狀況的影響。NotSupportedException
:若要求的作業對用戶端有效,但其目前狀態不支援,就會出現這個例外狀況。 您可以在Message
中找到此案例的相關資訊。AggregateException
:當作業可能遇到多個例外狀況,並將其呈現為單一失敗時,就會出現此情形。 啟動或停止服務匯流排處理器或服務匯流排工作階段處理器時,最常遇到此例外狀況。
原因:QuotaExceeded
ServiceBusException 若顯示 QuotaExceeded
原因,代表已超過某特定實體的配額。
注意
如需了解服務匯流排配額,請參閱配額 (機器翻譯)。
佇列和主題
在佇列和主題方面,問題通常在於佇列大小。 錯誤訊息屬性會包含進一步的詳細資訊,如下例所示:
Message: The maximum entity size has been reached or exceeded for Topic: 'xxx-xxx-xxx'.
Size of entity in bytes:1073742326, Max entity size in bytes:
1073741824..TrackingId:xxxxxxxxxxxxxxxxxxxxxxxxxx, TimeStamp:3/15/2013 7:50:18 AM
訊息指出主題超過其大小限制,本例為 1 GB (預設大小限制)。
命名空間
在命名空間方面,QuotaExceeded 例外狀況可能表示應用程式已超過命名空間的連線數目上限。 例如:
<tracking-id-guid>_G12 --->
System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]:
ConnectionsQuotaExceeded for namespace xxx.
常見的原因
這個錯誤有兩種常見原因︰無效信件佇列和訊息接收者無法正常運作。
無效信件佇列:讀取器無法完成訊息,當鎖定過期後,訊息會傳回佇列/主題。 如果讀取器遇到例外狀況,阻止其完成訊息,就會發生這個錯誤。 訊息讀取 10 次後,預設會移至無效信件佇列。 這種行為由 MaxDeliveryCount 屬性控制,預設值是 10。 訊息堆積在無效信件佇列中會佔用空間。
若要解決此問題,請閱讀和完成無效信件佇列中的訊息,就像您處理任何其他佇列一樣。
接收者停止。 收件者已停止接收佇列或訂用帳戶的訊息。 這個問題的識別方式是查看作用中訊息計數。 如果作用中訊息計數很高或不斷增加,表示訊息撰寫的速度超過讀取的速度。
原因:MessageLockLost
原因
ServiceBusException 若顯示 MessageLockLost
原因,代表訊息是使用 PeekLock (機器翻譯) 接收模式接收,且用戶端所保留的鎖定在服務端到期。
訊息上的鎖定可能會由於多種原因而到期:
- 鎖定計時器已在用戶端應用程式更新鎖定之前到期。
- 用戶端應用程式已取得鎖定,將其儲存至持續性存放區,然後重新啟動。 一旦重新啟動,用戶端應用程式就會查看傳遞中訊息,並嘗試完成這些訊息。
在下列案例中,您可能也會收到此例外狀況:
- 服務更新
- 作業系統更新
- 在保留鎖定時變更實體 (佇列、主題、訂用帳戶) 上的屬性。
解決方法
當用戶端應用程式收到 MessageLockLostException,便再也無法處理訊息。 用戶端應用程式可能會選擇性地考慮記錄例外狀況進行分析,但用戶端「必須」處置訊息。
由於訊息上的鎖定已到期,因此會回到佇列 (或訂用帳戶),並可由呼叫接收的下一個用戶端應用程式加以處理。
如果已超過 MaxDeliveryCount,則訊息可能會移至 DeadLetterQueue。
原因:SessionLockLost
原因
當工作階段獲得接受,且用戶端所保留的鎖定在服務端到期,便會擲回 ServiceBusException 與 MessageLockLost
原因。
工作階段上的鎖定可能會由於多種原因而到期:
- 鎖定計時器已在用戶端應用程式更新鎖定之前到期。
- 用戶端應用程式已取得鎖定,將其儲存至持續性存放區,然後重新啟動。 一旦重新啟動,用戶端應用程式就會查看傳遞中工作階段,並嘗試在這些工作階段中處理訊息。
在下列案例中,您可能也會收到此例外狀況:
- 服務更新
- 作業系統更新
- 在保留鎖定時變更實體 (佇列、主題、訂用帳戶) 上的屬性。
解決方法
當用戶端應用程式收到 SessionLockLostException,便再也無法處理工作階段中的訊息。 用戶端應用程式可能會考慮記錄例外狀況進行分析,但用戶端「必須」處置訊息。
由於工作階段上的鎖定已到期,因此會回到佇列 (或訂用帳戶),並可由接受該工作階段的下一個用戶端應用程式鎖定。 工作階段鎖定無論何時都只會由單一用戶端應用程式保留,因此一定能按順序處理。
TimeoutException
TimeoutException 表示使用者啟始作業所用的時間長過作業逾時。
您應該檢查 ServicePointManager.DefaultConnectionLimit 屬性的值,因為達到這個限制可能也會造成 TimeoutException。
在維護作業 (例如服務匯流排服務更新 (或) 執行服務資源上的作業系統更新) 期間或過程中,預期會發生逾時狀況。 在作業系統更新期間,實體會四處移動且節點會更新或重新開機,這可能會導致逾時。 如需 Azure 服務匯流排服務的服務等級協定 (SLA) 詳細資料,請參閱服務匯流排的 SLA。
SocketException
原因
下列情況會擲回 SocketException:
- 當連線嘗試因為主機未在指定的時間之後正確回應而失敗時 (TCP 錯誤碼 10060)。
- 已建立的連線失敗,因為連線的主機無法回應。
- 處理訊息時發生錯誤,或遠端主機超過逾時。
- 基礎網路資源問題。
解決方法
SocketException 錯誤表示裝載應用程式的 VM 無法將名稱 <mynamespace>.servicebus.windows.net
轉換為對應的 IP 位址。
查看下列命令是否成功對應至 IP 位址。
PS C:\> nslookup <mynamespace>.servicebus.windows.net
這應該會提供類似下方的輸出:
Name: <cloudappinstance>.cloudapp.net
Address: XX.XX.XXX.240
Aliases: <mynamespace>.servicebus.windows.net
如果上述名稱未解析為 IP 和命名空間別名,請洽詢網路管理員以進一步調查。 名稱解析是透過 DNS 伺服器 (通常是客戶網路中的資源) 完成。 如果 DNS 解析是由 Azure DNS 完成,請連絡 Azure 支援。
如果名稱解析如預期般運作,請在這裡 (機器翻譯) 檢查是否允許連線至 Azure 服務匯流排。
UnauthorizedAccessException
UnauthorizedAccessException 表示提供的認證不允許執行要求動作。 Message
屬性包含此失敗的詳細資料。
建議您建構 ServiceBusClient
時,根據提供的授權類型,按照下列驗證步驟操作。
- 確認連接字串正確無誤 (機器翻譯)
- 確認 SAS 權杖已正確產生 (機器翻譯)
- 確認已授與正確的角色型存取控制 (RBAC) 角色 (機器翻譯)
異地復寫例外狀況
ServerBusyException
原因
- 在異步復寫期間(復寫延隔時間大於零),用戶端會嘗試在服務總線實體上執行作業(佇列、主題)或執行管理作業,但是作業無法完成,因為主要區域與次要區域之間的復寫延遲已超過允許復寫延遲的上限,以秒為單位。
- 範例:作業正在進行節流處理,因為有了新的複寫延隔時間會達到 38323 秒,這大於設定的復寫延遲上限(300 秒)。 正在復寫之最新作業的目前復寫延遲為 0 秒。
- 實體的復寫佇列超過其位元組大小上限。 復寫佇列的大小上限是 服務匯流排 所設定的內部限制。
- 範例:復寫佇列大小 73128000 超過閾值67108864。
- 在同步復寫中,要求在等候另一個要求複寫時逾時。
- 範例:來自用戶端應用程式的大量 skarri-stroage-exp1(westus3)/q1:MessagingJournal 要求。 正在復寫至其他區域。
解決方法
- 客戶端應該關閉,讓服務有時間處理其指定的工作負載,然後客戶端應該重試。
Timeout
原因
- Geo DR 中的逾時例外狀況表示作業未在用戶端提供的逾時內完成。
- 在同步復寫中,作業的主要區域寫入和複寫至次要區域是在作業逾時範圍內。
- 在異步複寫中,作業的主要區域寫入是在作業逾時的範圍內,但作業複寫至次要區域的作業不在作業逾時的範圍內。
- 範例:作業未在物件訊息的已配置時間 00:01:00 內完成。 (ServiceTimeout)。
解決方法
- 用戶端應該重試作業。
- 請注意,逾時作業的某些步驟可能已完成。 逾時作業可能已寫入主要區域和某些次要區域。 如果作業已寫入主要區域,則不論用戶端逾時為何,它最終都會復寫到所有次要區域。
BadRequest
原因
- 在計劃性故障轉移期間,主要區域會暫時設定為只讀,以允許次要區域趕上。 如果用戶端在此暫時只讀狀態時嘗試對主要區域執行寫入作業,則用戶端將會收到 BadRequest 例外狀況。
- 範例:復寫角色切換進行中,主要複本:<entity-name> 為 ReadOnly。
解決方法
- 客戶端必須等候計劃性故障轉移完成,寫入作業才會成功。
- 如果計劃性故障轉移花費太長的時間,可以改為觸發強制故障轉移。
下一步
如需完整的服務匯流排 .NET API 參考資料,請參閱 Azure .NET API 參考資料。 如需疑難排解秘訣,請參閱疑難排解指南 (機器翻譯)。