共用方式為


自我修復設計

設計應用程式使其能夠在發生失敗時自我修復

在分散式系統中,失敗是不可避免的。 硬體可能會故障。 網路可能會暫時性故障。 整個服務、資料中心甚至 Azure 區域很少會遇到中斷的情況,但即使如此,在設計工作負載架構時仍需將這些情況納入考慮。 在您的工作負載設計中,應該及早考慮韌性和恢復能力。

因此,請將應用程式設計為發生失敗時能夠自我修復。 這需要從三方面著手:

  • 偵測失敗。
  • 優雅地回應失敗。
  • 記錄和監視失敗以提供操作深入解析。

回應特定失敗類型的方式取決於應用程式的可用性需求。 例如,如果需要高可用性,您可能會部署到區域中的多個可用性區域。 為了避免中斷,即使在整個 Azure 區域出現中斷 (這種情況不太可能發生) 的情況下,您也可以在區域中斷期間自動容錯移轉到次要地區。 不過,這種做法會比單一區域部署的成本更高且效能更低。

此外,不要只考慮像區域性中斷等通常很少發生的大事件。 您應該盡可能 (甚至更多) 地專注於處理本地的短期失敗,例如網路連線失敗或資料庫連結失敗。

建議

使用以非同步方式通訊的解耦元件。 在理想情況下,這些元件在時間和空間上是解耦的。 時間解耦意味著各個元件之間的通訊不需要同時存在,但仍然可以通訊。 空間解耦表示傳送者和接收者不必在同一個程序中執行,而是可以在更具效率的地方執行。 解耦的元件最好使用事件彼此通訊。 這有助於將串聯失敗的機會降到最低。

重試失敗的作業。 網路連線暫時失敗、資料庫連結中斷或服務忙碌而逾時都可能造成暫時性失敗。 在應用程式中建置重試邏輯以處理暫時性失敗。 針對許多 Azure 服務,用戶端 SDK 會實作自動重試。 有關更多資訊,請參閱暫時性失敗處理重試模式

保護失敗的遠端服務 (斷路器)。 在暫時性失敗之後重試是不錯的,但如果失敗持續發生,則可能會導致過多的呼叫者不斷請求一個失敗的服務。 這可能會導致要求備份時發生串聯失敗。 當作業可能失敗時,請使用斷路器模式快速檢錯 (而不進行遠端呼叫)。

隔離重要資源 (隔艙) 。 某個子系統中的失敗有時可能會串聯。 如果失敗導致執行續或通訊端等資源無法及時釋放,可能會導致資源耗盡,就會發生這種情況。 若要避免這種情況,請使用隔艙模式將系統分割成隔離的群組,讓某個分割區中的失敗不會導致整個系統關機。

執行負載平衡。 應用程式可能會遇到流量突然暴增的情況,進而導致後端的服務過載。 若要避免這種情況,請使用佇列型負載平衡模式來將工作項目排入佇列,以非同步方式執行。 佇列充當緩衝器,平滑負載峰值。

容錯移轉。 如果無法連線到執行個體,請容錯移轉至另一個執行個體。 對於無狀態的事物 (例如 Web 伺服器),請將多個執行個體放在負載平衡器或流量管理員後面。 對於儲存狀態的事務,例如資料庫,請使用複本和容錯移轉。 根據資料儲存和其複製方式,應用程式可能需要處理最終一致性。

補償失敗的交易。 一般而言,請避免分散式交易,因為它們需要跨服務和資源的協調。 相反地,請由較小的單一交易組成一個操作。 如果作業在中途失敗,請使用補償交易復原任何已完成的步驟。

檢查長時間執行的交易。 如果長時間執行的作業失敗,檢查點可以提供韌性。 當作業重新啟動時 (例如,它是由另一個 VM 擷取),可以從最後一個檢查點繼續。 請考慮實作機制,定期記錄工作的狀態資訊,並將此狀態儲存到可由執行該工作的任何執行個體存取的永久性儲存體中。 如此一來,如果該程序已關閉,則會使用其他執行個體,從最後一個檢查點繼續執行的工作。 有提供此功能的程式庫,例如 NServiceBusMassTransit。 它們會透明地保存狀態,這些間隔與 Azure Service Bus 中佇列的訊息處理一致。

正常降級,並在失敗期間保持回應。 有時您無法解決問題,但可以提供仍然有用的精簡功能。 請考慮顯示書籍目錄的應用程式。 如果該應用程式無法擷取封面的縮圖影像,它可能會顯示預留位置影像。 整個子系統對於該應用程式可能並不重要。 例如,在電子商務網站上,顯示產品建議的重要性可能不如處理訂單。

節流用戶端。 有時候,少數使用者會建立過多的負載,這會降低應用程式對其他使用者的可用性。 在此情況下,請對該用戶端進行一段時間的節流。 請參閱節流模式

封鎖惡意執行者。 僅僅因為您對用戶端節流,並不意味著用戶端有惡意行為。 這只表示用戶端已超過其服務配額。 但是,如果用戶端持續超過其配額或有其他不良行為,您可以將其封鎖。 定義頻外程序,讓使用者要求解除封鎖。

使用領導者選舉。 當您需要協調工作時,請使用領導者選舉來選取協調器。 如此一來,協調器就不是單一失敗點。 如果協調器失敗,則會選取新的協調器。 不要從頭開始實作領導者選舉演算法,而是考慮使用現成的解決方案,例如 Zookeeper。

使用錯誤插入進行測試。 很多時候,成功的路徑經過了充分的測試,但失敗的路徑卻沒有。 在執行失敗路徑之前,系統可能會在生產環境中執行很長一段時間。 使用錯誤插入,藉由觸發實際失敗或模擬失敗,測試系統對失敗的韌性。

採用混沌工程。 混沌工程會將失敗或異常狀況隨機插入生產執行個體,以擴充錯誤插入的概念。

使用可用性區域。 許多 Azure 區域都提供可用性區域 (即該區域內相互隔離的資料中心集群)。 某些 Azure 服務可以按區域部署,這可確保將它們放置在特定區域中,並有助於減少相同工作負載中的元件之間通訊的延遲。 或者,某些服務可以使用區域備援來部署,這表示 Azure 會自動跨區域複寫資源以達到高可用性。 請考慮哪一種方法為您的解決方案提供最佳取捨。 若要了解有關如何設計解決方案以使用可用性區域和區域的更多資訊,請參閱使用可用性區域和區域的建議

如需讓應用程式自我修復的結構化方法,請參閱為 Azure 設計可靠的應用程式