共用方式為


Azure 應用程式的失敗模式分析

失敗模式分析 (FMA) 是透過識別系統中可能的失敗點來建立系統彈性的程序。 應該在架構和設計階段納入 FMA,讓您可以一開始就將失敗復原建置至該系統。

以下是執行 FMA 的一般程序:

  1. 識別系統中的所有元件。 包含外部相依性,例如識別提供者、第三方服務等等。

  2. 識別每個元件可能發生的潛在失敗。 單一元件可能有多個失敗模式。 例如,您應該分別考慮讀取失敗和寫入失敗,因為它們的影響和可能的風險降低步驟會有所不同。

  3. 根據失敗模式的整體風險為每個失敗模式評分。 考量下列因素:

    • 失敗的可能性為何。 該失敗是否相對常見? 極其罕見? 您不需要確切的數字;目的是幫助確定優先順序。
    • 就可用性、資料遺失、貨幣成本和業務中斷而言,該失敗對應用程式有什麼影響?
  4. 判斷應用程式將如何回應和復原每個失敗模式。 請考量成本和應用程式複雜度之間的權衡。

作為 FMA 程序的起點,本文包含潛在失敗模式及其風險降低步驟的目錄。 該目錄是由技術或 Azure 服務所整理,再加上應用程式層級設計的一般類別。 該目錄並不詳盡,但涵蓋許多核心 Azure 服務。

注意

失敗應該與錯誤區別。 失敗是系統內發生的意外事件,導致系統無法繼續正常運作。 例如,硬體故障導致網路分割就是失敗。 通常,需要對失敗進行干預或針對該類失敗進行特定的設計。 而錯誤則是正常作業中可預期的部分,在發生時會立即處理,系統將在發生錯誤後繼續以相同的功能運作。 例如,在輸入驗證期間探索到的錯誤,可以透過商務邏輯來處理。

應用程式服務

App Service 應用程式關閉。

偵測。 可能的原因:

  • 預期的關機

    • 操作員關閉該應用程式;例如,使用 Azure 入口網站。
    • 該應用程式因為閒置而卸載。 (只有當 Always On 設定已停用時。)
  • 非預期的關機

    • 該應用程式當機。
    • App Service VM 執行個體無法使用。

Application_End 記錄將捕捉應用程式網域的關機 (軟進程當機),這是唯一捕捉應用程式網域關閉的方式。

復原:

  • 如果預期關機,請使用該應用程式的關機事件正常關機。 例如,在 ASP.NET 中,使用 Application_End 方法。
  • 如果該應用程式在閒置時卸載,則會在下一個要求時自動重新啟動。 不過,您將會產生「冷啟動」成本。
  • 若要防止應用程式在閒置時卸載,請在 Web 應用程式中啟用 Always On 設定。 請參閱在 Azure 應用程式服務中設定 Web 應用程式
  • 若要防止操作員關閉該應用程式,請使用 ReadOnly 層級設定資源鎖定。 請參閱使用 Azure Resource Manager 鎖定資源
  • 如果該應用程式當機或 App Service VM 無法使用,App Service 會自動重新啟動該應用程式。

診斷。 應用程式記錄和 Web 伺服器記錄。 請參閱在 Azure 應用程式服務中啟用 Web 應用程式的診斷記錄

特定使用者重複提出錯誤的要求或過載系統。

偵測。 驗證使用者,並在應用程式記錄中包含使用者 ID。

復原:

診斷。 記錄所有驗證要求。

部署了錯誤的更新。

偵測。 透過 Azure 入口網站監視應用程式健全狀態 (請參閱監視 Azure Web 應用程式效能),或實作健全狀態端點監視模式

復原:。 使用多個部署位置,並復原到最後一個已知良好的部署。 如需詳細資訊,請參閱基本 Web 應用程式

Microsoft Entra ID

OpenID Connect 驗證失敗。

偵測。 可能的失敗模式包括:

  1. Microsoft Entra ID 無法使用,或因為網路問題而無法連線。 重新導向至驗證端點失敗,而 OpenID Connect 中介軟體會擲回例外狀況。
  2. Microsoft Entra 租用戶不存在。 重新導向至驗證端點會傳回 HTTP 錯誤碼,而 OpenID Connect 中介軟體會擲回例外狀況。
  3. 使用者無法驗證。 不需要偵測策略;Microsoft Entra ID 會處理登入失敗。

復原:

  1. 捕捉來自中介軟體的未處理例外狀況。
  2. 處理 AuthenticationFailed 事件。
  3. 將該使用者重新導向至錯誤頁面。
  4. 使用者重試。

將資料寫入「Azure 搜尋服務」失敗。

偵測。 捕捉 Microsoft.Rest.Azure.CloudException 錯誤。

復原:

搜尋 .NET SDK 會在暫時性失敗後自動重試。 由用戶端 SDK 擲回的任何例外狀況都應該被視為非暫時性錯誤。

預設重試原則使用指數輪詢。 若要使用不同的重試原則,請在 SearchIndexClientSearchServiceClient 類別上呼叫 SetRetryPolicy。 如需詳細資訊,請參閱自動重試

診斷。 使用搜尋流量分析

從「Azure 搜尋服務」讀取資料失敗。

偵測。 捕捉 Microsoft.Rest.Azure.CloudException 錯誤。

復原:

搜尋 .NET SDK 會在暫時性失敗後自動重試。 由用戶端 SDK 擲回的任何例外狀況都應該被視為非暫時性錯誤。

預設重試原則使用指數輪詢。 若要使用不同的重試原則,請在 SearchIndexClientSearchServiceClient 類別上呼叫 SetRetryPolicy。 如需詳細資訊,請參閱自動重試

診斷。 使用搜尋流量分析

Cassandra

讀取或寫入節點失敗。

偵測。 捕捉例外狀況。 針對 .NET 用戶端,這通常是 System.Web.HttpException。 其他用戶端可能會有其他例外狀況類型。 有關更多資訊,請參閱正確處理 Cassandra 錯誤

復原:

  • 每個 Cassandra 用戶端都有自有的重試原則和功能。 有關更多資訊,請參閱正確處理 Cassandra 錯誤
  • 使用機架感知部署,並將資料節點分散到整個容錯網域。
  • 部署到具有本機仲裁一致性的多個區域。 如果發生非暫時性失敗,請轉移至另一個區域。

診斷。 應用程式記錄

雲端服務

Web 或背景工作角色意外關閉。

偵測。 會引發 RoleEnvironment.Stopping 事件。

復原。 覆寫 RoleEntryPoint.OnStop 方法以正常清除。 如需詳細資訊,請參閱處理 Azure OnStop 事件的正確方式 (部落格)

Azure Cosmos DB

讀取資料失敗。

偵測。 捕捉 System.Net.Http.HttpRequestExceptionMicrosoft.Azure.Documents.DocumentClientException

復原:

  • SDK 會自動重試失敗的嘗試。 若要設定重試次數和最長等待時間,請設定 ConnectionPolicy.RetryOptions。 用戶端引發的例外狀況超出重試原則,或不是暫時性錯誤。
  • 如果 Azure Cosmos DB 對用戶端進行節流,則會傳回 HTTP 429 錯誤。 檢查 DocumentClientException 中的狀態碼。 如果您持續收到錯誤 429,建議考慮提高該集合的輸送量值。
    • 如果您使用 MongoDB API,該服務會在節流時傳回錯誤碼 16500。
  • 當您使用支援可用性區域的區域時,請啟用區域備援。 當您使用區域備援時,Azure Cosmos DB 會在發生區域中斷時自動容錯移轉。 如需更多資訊,請參閱使用 Azure Cosmos DB 達到高可用性
  • 如果您要設計多區域解決方案,請跨兩個以上區域複寫 Azure Cosmos DB 資料庫。 所有複本都是可讀取的。 使用用戶端 SDK,指定 PreferredLocations 參數。 這是已排序的 Azure 區域清單。 所有讀取都將傳送到清單中的第一個可用區域。 如果該要求失敗,用戶端會依序嘗試清單中的其他區域。 如需詳細資訊,請參閱如何在適用於 NoSQL 的 Azure Cosmos DB 中設定全域散發

診斷。 記錄用戶端上的所有錯誤。

寫入資料失敗。

偵測。 捕捉 System.Net.Http.HttpRequestExceptionMicrosoft.Azure.Documents.DocumentClientException

復原:

  • SDK 會自動重試失敗的嘗試。 若要設定重試次數和最長等待時間,請設定 ConnectionPolicy.RetryOptions。 用戶端引發的例外狀況超出重試原則,或不是暫時性錯誤。
  • 如果 Azure Cosmos DB 對用戶端進行節流,則會傳回 HTTP 429 錯誤。 檢查 DocumentClientException 中的狀態碼。 如果您持續收到錯誤 429,建議考慮提高該集合的輸送量值。
  • 當您使用支援可用性區域的區域時,請啟用區域備援。 當您使用區域備援時,Azure Cosmos DB 會同步複寫可用性區域的所有寫入。 如需更多資訊,請參閱使用 Azure Cosmos DB 達到高可用性
  • 如果您要設計多區域解決方案,請跨兩個以上區域複寫 Azure Cosmos DB 資料庫。 如果主要區域失敗,則會將另一個區域升級以寫入。 容錯移轉也可以手動觸發。 SDK 會執行自動探索和路由,因此應用程式程式碼會在容錯移轉之後繼續運作。 在容錯移轉期間 (通常是在幾分鐘內完成),因為 SDK 會尋找新的寫入區域所以寫入作業會延遲較久。 如需詳細資訊,請參閱如何在適用於 NoSQL 的 Azure Cosmos DB 中設定全域散發
  • 本文件會被保留在備份佇列以作為後援,並在之後處理該佇列。

診斷。 記錄用戶端上的所有錯誤。

佇列儲存體

將訊息寫入 Azure 佇列儲存體持續失敗。

偵測。 在 N 次重試嘗試之後,寫入作業仍失敗。

復原:

  • 將資料儲存在本機快取中,並在服務可供使用時將寫入轉送至儲存體。
  • 建立次要佇列,並在主要佇列無法使用時寫入該佇列。

診斷。 使用儲存體計量

該應用程式無法處理來自佇列的特定訊息。

偵測。 特定應用程式。 例如,訊息包含無效的資料,或商務邏輯因某些原因而失敗。

復原:

將該訊息移至個別的佇列。 執行個別流程來檢查該佇列中的訊息。

請考慮使用 Azure 服務匯流排傳訊佇列,此功能會提供用於此目的之無效信件佇列功能。

注意

如果您使用儲存體佇列搭配 WebJobs,WebJobs SDK 內建了有害訊息處理功能。 請參閱如何透過 WebJobs SDK 使用 Azure 佇列儲存體

診斷。 使用應用程式記錄。

Azure Cache for Redis

從快取讀取失敗。

偵測。 捕捉 StackExchange.Redis.RedisConnectionException

復原:

  1. 重試暫時性失敗。 Azure Cache for Redis 支援內建重試。 有關詳細資訊,請參閱 Azure Cache for Redis 重試指引
  2. 將非暫時性失敗視為快取遺漏,並回到原始資料來源。

診斷。 使用 Azure Cache for Redis 診斷

寫入快取失敗。

偵測。 捕捉 StackExchange.Redis.RedisConnectionException

復原:

  1. 重試暫時性失敗。 Azure Cache for Redis 支援內建重試。 有關詳細資訊,請參閱 Azure Cache for Redis 重試指引
  2. 如果該錯誤是非暫時性的,請將其忽略並讓其他交易稍後寫入快取。

診斷。 使用 Azure Cache for Redis 診斷

SQL Database

無法連接到主要區域的資料庫。

偵測。 連接失敗。

復原:

  • 啟用區域備援。 藉由啟用區域備援,Azure SQL 資料庫會自動在支援區域內的多個 Azure 可用性區域複寫您的寫入。 有關更多資訊,請參閱區域備援可用性

  • 啟用異地複寫。 如果您要設計多區域解決方案,請考慮啟用 SQL 資料庫作用中異地複寫。

    必要條件:資料庫必須設定為作用中異地複寫。 請參閱 SQL 資料庫作用中異地複寫

    複本使用不同的連接字串,因此您必須更新應用程式中的連接字串。

用戶端在連接集區中用盡連接。

偵測。 捕捉 System.InvalidOperationException 錯誤。

復原:

  • 重試作業。
  • 作為風險降低計劃,請隔離每個使用案例的連接集區,讓一個使用案例無法主宰所有連接。
  • 增加最大連接集區。

診斷。 應用程式記錄。

達到資料庫連結限制。

偵測。 Azure SQL 資料庫會限制並行背景工作、登入和工作階段的數量。 該限制取決於服務層級。 如需詳細資訊,請參閱 Azure SQL 資料庫資源限制

若要偵測這些錯誤,請捕捉 System.Data.SqlClient.SqlException 並檢查 SqlException.Number 的值是否有 SQL 錯誤碼。 如需相關錯誤碼的清單,請參閱 SQL 資料庫用戶端應用程式的 SQL 錯誤碼:資料庫連結錯誤和其他問題

復原。 這些錯誤會被視為暫時性錯誤,因此重試可能會解決該問題。 如果您持續遇到這些錯誤,請考慮縮放資料庫。

診斷。 - sys.event_log 查詢會傳回成功的資料庫連結、連接失敗和死結。

服務匯流排傳訊

從「服務匯流排」佇列讀取消息失敗。

偵測。 捕捉來自用戶端 SDK 的例外狀況。 「服務匯流排」例外狀況的基底類別是 MessagingException。 如果該錯誤是暫時性的,則 IsTransient 屬性為 true。

有關詳細資訊,請參閱服務匯流排傳訊例外狀況

復原:

  1. 重試暫時性失敗。 請參閱服務匯流排重試指引
  2. 無法傳遞給任何接收者的訊息會放置於無效信件佇列。 使用此佇列來查看無法接收哪些訊息。 無效信件佇列不會自動清除。 這些訊息會保留在該處,直到您明確擷取它們為止。 請參閱服務匯流排無效信件佇列概觀

將訊息寫入「服務匯流排」佇列失敗。

偵測。 捕捉來自用戶端 SDK 的例外狀況。 「服務匯流排」例外狀況的基底類別是 MessagingException。 如果該錯誤是暫時性的,則 IsTransient 屬性為 true。

有關詳細資訊,請參閱服務匯流排傳訊例外狀況

復原:

  • 「服務匯流排」用戶端會在暫時性錯誤之後自動重試。 根據預設,它會使用指數輪詢。 在達到重試計數上限或逾時期間上限之後,用戶端會擲回例外狀況。 如需詳細資訊,請參閱服務匯流排重試指引

  • 如果超過佇列配額,用戶端會擲回 QuotaExceededException。 例外狀況訊息提供了更多詳細資訊。 在重試之前,先從佇列清空一些訊息,並考慮使用「斷路器」模式,以避免在超過配額時繼續重試。 此外,請確保未將 BrokeredMessage.TimeToLive 屬性設定太高。

  • 在區域內,可以使用分割的佇列或主題來改善復原。 未分割的佇列或主題會指派給一個傳訊存放區。 如果無法使用此傳訊存放區,該佇列或主題上的所有作業都會失敗。 分割的佇列或主題會被分割到多個傳訊存放區。

  • 使用區域備援自動複寫多個可用性區域之間的變更。 如果一個可用性區域失敗,就會自動發生容錯移轉。 有關詳細資訊,請參閱使應用程式免受服務匯流排中斷與災害影響的最佳做法

  • 如果您要設計多區域解決方案,請在不同的區域中建立兩個「服務匯流排」命名空間,並複寫這些訊息。 您可以使用主動式複寫或被動式複寫。

    • 主動式複寫:用戶端會將每個訊息傳送至這兩個佇列。 接收者會接聽這兩個佇列。 使用唯一識別碼標記訊息,讓用戶端可以捨棄重複的訊息。
    • 被動式複寫:用戶端會將訊息傳送至一個佇列。 如果發生錯誤,用戶端會回復至另一個佇列。 接收者會接聽這兩個佇列。 此方法可減少傳送之重複訊息的數目。 不過,接收者仍必須處理重複的訊息。

    如需詳細資訊,請參閱 GeoReplication 範例使應用程式免受服務匯流排中斷與災害影響的最佳做法

重複訊息。

偵測。 檢查訊息的 MessageIdDeliveryCount 屬性。

復原:

  • 可能的話,請將訊息處理作業設計為等冪。 否則,儲存已經處理之訊息的訊息 ID,並在處理訊息之前檢查該 ID。

  • 透過建立將 RequiresDuplicateDetection 設定為 true 的佇列來啟用重複偵測。 使用此設定,「服務匯流排」會自動刪除與上一條訊息具有相同 MessageId 的任何訊息。 請注意以下要點:

    • 此設定可防止將重複的訊息放入佇列中。 它不會防止接收者多次處理相同的訊息。
    • 重複資料偵測具有時間範圍。 如果重複資料傳送到此視窗以外,則不會偵測到。

診斷。 記錄重複的訊息。

該應用程式無法處理來自佇列的特定訊息。

偵測。 特定應用程式。 例如,訊息包含無效的資料,或商務邏輯因某些原因而失敗。

復原:

需要考量兩種失敗模式。

  • 接收者偵測失敗。 在這種情況下,請將該訊息移動到無效信件佇列。 稍後,執行個別的程序來檢查無效信件佇列中的訊息。
  • 接收者在處理訊息時失敗,例如,由於未處理的例外狀況。 若要處理此案例,請使用 PeekLock 模式。 在此模式中,如果鎖定過期,其他接收者就可使用該訊息。 如果訊息超過傳遞計數上限或存留時間,該訊息會自動移至無效信件佇列。

如需詳細資訊,請參閱服務匯流排寄不出的信件佇列的概觀

診斷。 每當應用程式將訊息移至無效信件佇列時,就會將事件寫入應用程式記錄。

儲存體

將資料寫入 Azure 儲存體失敗

偵測。 用戶端會在寫入時收到錯誤訊息。

復原:

  1. 重試作業,以從暫時性失敗中復原。 用戶端 SDK 中的重試原則會自動處理此動作。

  2. 實作「斷路器」模式,以避免過度儲存。

  3. 如果 N 次重試嘗試失敗,請執行正常後援。 例如:

    • 將資料儲存在本機快取中,並在服務可供使用時將寫入轉送至儲存體。
    • 如果寫入動作位於交易範圍中,請補償該交易。

診斷。 使用儲存體計量

從 Azure 儲存體讀取資料失敗。

偵測。 用戶端會在讀取時收到錯誤訊息。

復原:

  1. 重試作業,以從暫時性失敗中復原。 用戶端 SDK 中的重試原則會自動處理此動作。
  2. 針對RA-GRS 儲存體,如果從主要端點讀取失敗,請嘗試從次要端點讀取。 用戶端 SDK 可以自動處理此問題。 請參閱 Azure 儲存體複寫
  3. 如果 N 次重試嘗試失敗,請採取後援動作以正常降級。 例如,如果無法從儲存體擷取產品映像,則顯示一般預留位置影像。

診斷。 使用儲存體計量

虛擬機器

與後端 VM 的連接失敗。

偵測。 網路連接錯誤。

復原:

  • 在負載平衡器後方的可用性設定組中部署至少兩個後端 VM。
  • 如果連接錯誤是暫時性的,有時 TCP 會成功重試傳送該訊息。
  • 在該應用程式中實作重試原則。
  • 針對持續性或非暫時性錯誤,請實作斷路器模式。
  • 如果呼叫的 VM 超過其網路輸出限制,將會填滿輸出佇列。 如果輸出佇列持續處於滿載狀態,請考慮擴充。

診斷。 記錄在服務界限的事件。

VM 執行個體無法使用或狀況不良。

偵測。 設定負載平衡器健全狀態探查,以指示 VM 執行個體的健全狀態。 探查應該檢查重要的功能是否正確回應。

復原。 針對每個應用程式層,將多個 VM 執行個體放入相同的可用性設定組中,並將負載平衡器放在 VM 前面。 如果健全狀態探查失敗,該負載均衡器將停止向狀況不良的執行個體傳送新連接。

診斷。 - 使用 Load Balancer 記錄分析

  • 設定監視系統以監視所有健全狀態監視端點。

操作員意外關閉 VM。

偵測。 N/A

復原。 使用 ReadOnly 層級設定資源鎖定。 請參閱使用 Azure Resource Manager 鎖定資源

診斷。 使用 Azure 活動記錄

WebJobs

當 SCM 主機閒置時,連續作業會停止執行。

偵測。 將取消權杖傳遞至 WebJob 函式。 如需詳細資訊,請參閱正常關機

復原。 啟用 Web 應用程式中的 Always On 設定。 如需詳細資訊,請參閱搭配 WebJobs 執行背景工作

應用程式設計

應用程式無法處理突增的傳入要求。

偵測。 取決於該應用程式。 一般徵兆:

  • 網站會開始傳回 HTTP 5xx 錯誤碼。
  • 相依服務,例如資料庫或儲存體,會開始節流要求。 視服務而定,尋找 HTTP 429 (要求太多) 之類的 HTTP 錯誤。
  • HTTP 佇列長度會成長。

復原:

  • 擴增以處理增加的負載。

  • 緩解失敗,以避免串聯失敗破壞整個應用程式。 緩解策略包括:

    • 實作節流模式,以避免後端系統過載。
    • 使用佇列型負載層級來緩衝要求,並以適當的步調處理要求。
    • 優先處理某些用戶端。 例如,如果該應用程式具有免費層和付費層,請對免費層而非付費層的客戶進行節流。 請參閱優先順序佇列模式

診斷。 使用應用程式服務診斷記錄。 使用 Azure Log AnalyticsApplication InsightsNew Relic 等服務來協助了解診斷記錄。

範例在此提供。 它會針對這些例外狀況使用 Polly

  • 429 - 節流
  • 408 - 逾時
  • 401 - 未經授權
  • 503 或 5xx - 服務無法使用

工作流程或分散式交易中的其中一個作業失敗。

偵測。 在 N 次重試嘗試之後,仍會失敗。

復原:

  • 作為風險降低計劃,請實作排程器代理程式監督員模式來管理整個工作流程。
  • 不要在逾時時重試。 此錯誤的成功率很低。
  • 佇列工作,以便稍後重試。

診斷。 記錄所有作業 (成功且失敗),包括補償動作。 使用關聯性 ID,讓您可以追蹤相同交易內的所有作業。

對遠端服務的呼叫失敗。

偵測。 HTTP 錯誤碼。

復原:

  1. 重試暫時性失敗。
  2. 如果呼叫在 N 次嘗試之後失敗,請採取後援動作。 (特定應用程式。)
  3. 實作斷路器模式,以避免串聯失敗。

診斷。 記錄所有遠端呼叫失敗。

下一步

請參閱 Azure Well-Architected Framework 中的復原和相依性。 在開始進行架構和設計階段時就應該將失敗復原納入系統,以避免失敗風險。