編輯

共用方式為


重試模式

Azure

藉由以透明方式重試失敗的作業,讓應用程式在嘗試連線到服務或網路資源時處理暫時性失敗。 這可以改善應用程式的穩定性。

內容和問題

應用程式若要與在雲端中執行的元素通訊,必須能感應在此環境中發生的暫時性錯誤。 錯誤包括暫時遺失對元件和服務的網路連線、暫時無法使用服務,或服務忙碌時發生的逾時。

這些錯誤通常是自我更正,而且如果觸發錯誤的動作在適當延遲之後重複,可能會成功。 例如,處理大量並行要求的資料庫服務可以實 作節流策略 ,以暫時拒絕任何進一步的要求,直到工作負載放寬為止。 嘗試存取資料庫的應用程式可能無法連線,但如果應用程式在延遲之後再次嘗試,可能會成功。

解決方案

在雲端中,應該預期暫時性錯誤,且應用程式應設計為以簡潔且透明的方式處理它們。 這麼做可將錯誤對應用程式執行之商務工作的影響降到最低。 最常見的設計模式是引進重試機制。

使用重試模式叫用託管服務中作業的圖表

上圖說明使用重試機制叫用託管服務中的作業。 如果要求在預先定義的嘗試次數之後失敗,應用程式應該將錯誤視為例外狀況並據以處理。

注意

由於暫時性錯誤的常見本質,許多用戶端連結庫和雲端服務現在都提供內建重試機制,對於重試次數上限、重試之間的延遲和其他參數,具有某種程度的可設定性。 您可以在這裡找到許多 Azure 服務的內建重試支援,而 Microsof Entity Framework 提供重試失敗資料庫作業的功能。

重試策略

如果應用程式嘗試將要求傳送至遠端服務時偵測到失敗,則可以使用下列策略來處理失敗:

  • 取消。 如果錯誤指出失敗不是暫時性的,或者如果重複,則應用程式應該取消作業並回報例外狀況。

  • 立即重試。 如果報告的特定錯誤不尋常或罕見,例如網路封包在傳輸時損毀,最好的動作可能是立即重試要求。

  • 延遲後重試。 如果錯誤是由其中一個較常見的連線或忙碌失敗所造成,網路或服務可能需要一小段時間,而聯機問題已修正或清除工作積壓,因此以程式設計方式延遲重試是不錯的策略。 在許多情況下,應該選擇重試之間的期間,以盡可能平均地分散來自應用程式多個實例的要求,以減少忙碌服務繼續超載的機會。

如果要求仍然失敗,應用程式可以等候並嘗試另一次。 如有必要,此程式可以重複,並增加重試嘗試之間的延遲,直到嘗試了一些要求數目上限為止。 延遲可以累加或指數方式增加,視失敗類型以及在此期間更正的機率而定。

應用程式應該包裝所有嘗試,以程式代碼存取遠端服務,以實作符合上述其中一個策略的重試原則。 傳送至不同服務的要求可能會受限於不同的原則。

應用程式應該記錄錯誤和失敗作業的詳細數據。 這項資訊對運算子很有用。 也就是說,為了避免洪水操作員收到後續重試嘗試成功的作業警示,最好將早期失敗記錄為 參考專案 ,並只將最後一次重試嘗試失敗的失敗記錄為實際錯誤。 以下是此記錄模型的外觀範例。

如果服務經常無法使用或忙碌,通常是因為服務已耗盡其資源。 您可以藉由相應放大服務來減少這些錯誤的頻率。 例如,如果資料庫服務持續多載,則分割資料庫並將負載分散到多部伺服器可能很有説明。

問題和考量

決定如何實作此模式時,您應該考慮下列幾點。

對效能的影響

應調整重試原則,以符合應用程式的商務需求和失敗的性質。 對於某些非關鍵作業,最好快速失敗,而不是重試數次,並影響應用程式的輸送量。 例如,在存取遠端服務的互動式 Web 應用程式中,最好是在重試嘗試之間只有短暫延遲的少量重試之後失敗,並向使用者顯示適當的訊息(例如,「請稍後再試一次」)。 針對批次應用程式,可能更適合增加嘗試次數,並增加嘗試之間的延遲指數。

嘗試與大量重試之間延遲最少的主動式重試原則可能會進一步降低接近或容量的忙碌服務。 如果應用程式持續嘗試執行失敗的作業,此重試原則也會影響應用程式的回應性。

如果要求在大量重試之後仍然失敗,應用程式最好防止進一步的要求移至相同的資源,並直接立即回報失敗。 當期間到期時,應用程式可以暫時允許一或多個要求,以查看其是否成功。 如需此策略的詳細資訊,請參閱 斷路器模式

等冪

請考慮作業是否為等冪。 如果是,則重試原本就很安全。 否則,重試可能會導致作業多次執行,併產生非預期的副作用。 例如,服務可能會接收要求、成功處理要求,但無法傳送回應。 此時,重試邏輯可能會重新傳送要求,前提是未收到第一個要求。

例外狀況類型

針對服務的要求可能會因為各種原因而失敗,而引發不同的例外狀況,視失敗的性質而定。 某些例外狀況表示可快速解決的失敗,而其他例外狀況則表示失敗持續時間較長。 重試原則適合根據例外狀況類型調整重試嘗試之間的時間。

交易一致性

請考慮重試屬於交易一部分的作業將如何影響整體交易一致性。 微調交易作業的重試原則,以最大化成功的機會,並減少復原所有交易步驟的需求。

一般指導

  • 請確定所有重試程式代碼都已針對各種失敗狀況進行完整測試。 檢查它不會影響應用程式的效能或可靠性、對服務和資源造成過多負載,或產生競爭狀況或瓶頸。

  • 只有在了解失敗作業的完整內容時,才實作重試邏輯。 例如,如果包含重試原則的工作叫用另一個同時包含重試原則的工作,這個額外的重試層可能會為處理增加長時間的延遲。 最好將較低層級的工作設定為快速失敗,並將失敗的原因回報給叫用它的工作。 此較高層級的工作接著可以根據自己的原則來處理失敗。

  • 記錄導致重試的所有連線失敗,以便識別應用程式、服務或資源的根本問題。

  • 調查服務或資源最有可能發生的錯誤,以探索它們是否可能是長期或終端機。 如果是,最好以例外狀況處理錯誤。 應用程式可以報告或記錄例外狀況,然後嘗試叫用替代服務(如果有的話),或提供降級的功能來繼續。 如需如何偵測及處理長期錯誤的詳細資訊,請參閱 斷路器模式

使用此模式的時機

當應用程式與遠端服務互動或存取遠端資源時,可能會發生暫時性錯誤時,請使用此模式。 這些錯誤預期會短暫存在,而且重複先前失敗的要求可能會在後續嘗試時成功。

此模式可能沒有用處:

  • 當錯誤可能持續很長時間時,因為這可能會影響應用程式的回應性。 應用程式可能會浪費時間和資源,而嘗試重複可能會失敗的要求。
  • 針對處理因暫時性錯誤而造成的失敗,例如應用程式商業規則錯誤所造成的內部例外狀況。
  • 作為解決系統中延展性問題的替代方案。 如果應用程式遇到經常忙碌的錯誤,通常表示應該相應增加要存取的服務或資源。

工作負載設計

架構設計人員應該評估如何在工作負載的設計中使用重試模式,以解決 Azure 架構架構要素涵蓋的目標和原則。 例如:

要素 此模式如何支援支柱目標
可靠性設計決策可協助工作負載復原到故障,並確保它會在發生失敗后復原到完全正常運作的狀態。 減輕分散式系統中的暫時性錯誤是改善工作負載復原能力的核心技術。

- RE:07 自我保護
- RE:07 暫時性錯誤

如同任何設計決策,請考慮對其他可能以此模式導入之目標的任何取捨。

範例

如需 使用 Azure SDK 搭配內建重試機制支援的詳細範例,請參閱使用 .NET 實作重試原則指南。

下一步

  • 在撰寫自定義重試邏輯之前,請考慮使用一般架構,例如 適用於 .NET 的 Polly適用於 Java 的 Resilience4j

  • 處理變更商務數據的命令時,請注意重試可能會導致執行兩次動作,如果該動作像是向客戶的信用卡收費,可能會造成問題。 使用此部落格文章中所述的等冪模式有助於處理這些情況。

  • 可靠的 Web 應用程式模式 示範如何將重試模式套用至聚合在雲端上的 Web 應用程式。

  • 針對大部分的 Azure 服務,用戶端 SDK 包含內建的重試邏輯。 如需詳細資訊,請參閱 Azure 服務的重試指導

  • 斷路器模式。 如果失敗預期更持久,可能更適合實作斷路器模式。 結合重試和斷路器模式提供處理錯誤的完整方法。