天天看點

雲計算設計模式(十八)——重試模式 雲計算設計模式(十八)——重試模式

啟用應用程式來處理預期的,暫時的失敗時,它會嘗試連接配接到由透明的重試操作了以前失敗的期望,失敗的原因是瞬時的服務或網絡資源。這種模式可以提高應用程式的穩定性。

該通信的應用程式與在雲中運作的元素必須是可能發生在這樣的環境中的瞬時故障敏感。這些故障包括網絡連接配接的過程中出現時,一個服務是忙碌的瞬時損失的元件和服務中,服務的臨時不可用,或逾時。

這些故障一般是自校正的,如果經過一個合适的延遲被重複觸發一個故障的動作很可能是成功的。例如,資料庫服務,它正在處理大量并發請求可以實作節流政策,暫時拒絕,直到它的工作量有所緩和任何進一步的請求。試圖通路該資料庫的應用程式可能無法連接配接,但如果它經過一個合适的延遲再次嘗試它可能會成功。

在雲中,瞬時故障的情況并不少見和應用應該被設計為優雅和透明地處理它們,減少的影響,這種故障可能對應用程式正在執行業務任務。

如果一個應用程式檢測到故障時,它試圖将請求發送到遠端服務,它可以通過使用以下政策處理失敗:

•如果故障訓示故障不是瞬時的或不太成功,如果重複(例如,所造成的無效提供憑據的認證失敗是不可能成功的,無論是多少次未遂),應用程式應中止操作和報告一個合适的異常。

•如果報道的具體故障是不尋常的或罕見的,這可能是由于反常的情況,如網絡資料包成為損壞,同時它被發送。在這種情況下,應用程式可以再次立即重試失敗的請求,因為相同的故障是不可能被重複和請求将可能是成功的。

•如果故障是由一種更加普遍的連接配接,或“忙”的失敗,網絡或服務可能需要在短期内同時連接配接問題糾正或工作的積壓被清除。應用程式應該等待請求重試前一個合适的時間。

對于比較常見的短暫故障,重試期間,應選擇以傳播從應用程式中盡可能均勻的多個執行個體的請求。這可以減少繁忙的業務持續過載的可能性。如果一個應用程式的多個執行個體不斷轟擊與重試請求的服務,則可能需要該服務更長的時間來恢複。

如果請求仍然失敗,應用程式可以等待進一步的時期,再次嘗試。如果需要的話,這個過程可以重複而增加重試的延遲,直到請求的某一最大數目已經嘗試都失敗了。延遲時間可以逐漸增加,或可使用的定時政策,如指數回退,取決于故障的性質和可能性,這将在這段時間内被校正。

圖1示出了這種模式。如果嘗試後的預定數量的請求不成功,應用程式應将故障為異常,并相應地處理它。

雲計算設計模式(十八)——重試模式 雲計算設計模式(十八)——重試模式

圖1 - 使用重試模式中調用托管服務的操作

應用程式應該換所有試圖通路遠端服務,實作重試政策配套上面列出的政策之一的代碼。發送到不同的服務請求會受到不同的政策,有的供應商提供封裝這種方法庫。這些庫通常執行的政策是參數化的,而應用程式開發人員可以指定,如重試次數和重試之間的時間項的值。

在檢測故障和重試失敗的操作都應該記錄這些故障的詳細資訊的應用程式的代碼。這個資訊可能是有用的運算符。如果一個服務被頻繁報道為不可用或忙,往往是因為該服務已耗盡其資源。則可以減少與這些故障發生時通過換算出該服務的頻率。例如,如果資料庫服務正在不斷超載,它可能是有利的分區資料庫和負載分散到多個伺服器。

注意:

微軟Azure提供了重試模式的廣泛支援。該模式與實踐瞬态故障處理塊允許應用程式通過一系列的重試政策來處理許多Azure服務瞬态故障。微軟實體架構版本6提供了用于重新嘗試資料庫操作。此外,許多在Azure

Service Bus和Azure存儲的API透明地執行重試邏輯。

在決定如何實作這個模式時,您應考慮以下幾點:

•重試政策應進行調整,以滿足應用和故障性質的業務需求。它可能是更好一些非關鍵操作失敗快而不是重試幾次,并影響應用程式的吞吐量。例如,在試圖通路遠端服務的互動式Web應用程式,這可能是更好的重試之後用重試之間隻有一個短的延遲的數量較少失敗,并顯示一個适當的消息給使用者(例如,“請稍後“),再次嘗試阻止應用程式變得反應遲鈍。對于批處理應用程式,它可以是更合适的,以增加重試嘗試的次數與嘗試之間的指數增加的延遲。

•與嘗試之間最小的延遲和大量的重試的高攻擊重試的政策,可能會進一步降低正在接近運作或容量的占用。此重試政策也可能會影響應用程式的響應,如果它被不斷地在嘗試執行失敗的操作,而不是做有用功。

•如果後一個顯著次數的重試請求仍然失敗,則可能是更好的應用程式,以防止進一步的請求将要在相同的資源為一個周期,并簡單地立即報告故障。當期限屆滿後,該應用程式可以暫時允許通過一個或多個請求,看看他們是否成功。對于這一政策的詳細資訊,請參閱斷路器格局。

•在由它實作了一個重試政策可能需要為幂等的應用程式調用的服務的操作。例如,發送到服務的請求可以被接收和處理成功,但是,由于瞬時故障,它可能無法發送響應,訓示該處理已完成。然後在應用程式的重試邏輯可能試圖重複上沒有接收到所述第一請求的假定該請求。

•一個請求到服務失敗可能由于各種原因而提出不同的異常,根據故障的性質。一些例外可訓示故障,可以非常迅速地得到解決,而另一些可能表明該故障持續時間更長。可能是有益的重試政策,調整基于所述異常的類型的重試嘗試之間的時間。

•考慮如何重試的操作是事務的一部分,會影響整體交易的一緻性。這可能是有用的微調對于事務性操作的重試政策,最大限度地取得成功的機會,并減少需要撤消所有交易步驟。

•確定所有重試代碼是完全針對各種故障條件下進行測試。檢查它不會嚴重影響應用程式的性能或可靠性,導緻在服務和資源的過度負荷,或産生競态條件或瓶頸。

•實作隻在一個失敗的操作的全方面了解重試邏輯。例如,如果包含的重試政策任務調用另一個任務還包含一個重試政策,這個額外的重試的層可加長的延遲的處理。它可能是更好的配置的低級任務失敗快速并報告失敗傳回調用它的任務的原因。然後這個更進階别的任務可以決定如何處理是根據它自己的政策失效。

•記錄所有的連接配接故障,提示了重試,使潛在的問題與該應用程式,服務或資源可以被識别是很重要的。

•研究是最有可能發生于一個服務或資源發現,如果它們有可能是持久或終端的故障。如果是這樣的話,它可能是更好地處理該故障為異常。該應用程式可以報告或記錄該異常,然後試圖通過調用另一個服務,持續或者(如果有一個可用的),或通過提供降級功能。關于如何檢測和處理持久故障的更多資訊,請參閱斷路器格局。

使用這種模式:

•當一個應用程式可能會經曆短暫的故障,因為它與遠端服務進行互動,或通路遠端資源。這些故障預計将是短暫的,并重複了以前沒有能夠成功的後續嘗試的請求。

這種模式可能不适合:

•當故障很可能是持久的,因為這可能會影響應用程式的響應性。該應用程式可以簡單地是浪費時間和資源試圖重複請求是最有可能失敗。

•對于處理故障是不因瞬時故障,如在應用程式的業務邏輯引起錯誤的内部的異常。

•作為一種替代解決系統中的可擴充性問題。如果一個應用程式有頻繁的“忙”的故障,這是通常訓示被通路的服務或資源應相應加大。

本實施例說明的重試模式的實作。該OperationWithBasicRetryAsync方法,如下所示,通過TransientOperationAsync方法異步調用外部服務(該方法的細節将特定于服務,并從樣本代碼被省略)。

調用此方法的聲明被包裹在一個循環一個try/

catch塊中封裝。如果調用TransientOperationAsync方法成功,沒有抛出異常的for循環退出。如果TransientOperationAsync方法失敗,catch塊檢查為失敗的原因,并且如果它被認為是一個瞬時錯誤代碼等待一個短暫的延時,然後重試該操作。

在for循環還跟蹤該操作已經嘗試的次數,并且如果代碼失敗三次異常被認為是更持久。如果該異常是不是暫時的,或者是長久的,catch處理抛出的異常。此異常退出for循環,應捕獲調用該OperationWithBasicRetryAsync方法的代碼。

該IsTransient方法,如下所示,檢查是否有特定的一組是相關的,其中所述代碼運作的環境的異常。一過異常的定義可以根據被通路的資源,并在其上執行的操作環境的不同而不同。