處理 Azure Logic Apps 中的錯誤和例外狀況

適當地處理相依系統所造成的停機情況或問題,對任何整合架構來說都是種挑戰。 為了協助您建立穩固且具有恢復能力的整合方案來處理問題與失敗,Logic Apps 提供了一流的錯誤和例外狀況處理體驗。

重試原則

針對最基本的例外狀況和錯誤處理,您可以在任何支援的動作或觸發程式中使用 重試原則 ,例如,查看 HTTP 動作。 此重試原則會定義當原始要求逾時或失敗時 (也就是,任何造成 408、429 或 5xx 回應的要求),動作或觸發程序是否要重試要求,以及要如何重試。 如果未使用任何其他重試原則,則會使用預設原則。

以下是重試原則的類型:

類型 描述
預設值 此原則會以 指數漸增 的間隔 (依 7.5 秒調整,但限制在 5 到 45 秒之間) 傳送最多 4 次重試。
指數間隔 此原則會先等待選自指數成長範圍內的隨機間隔時間,再傳送下一個要求。
固定間隔 此原則會先等待指定的間隔時間,再傳送下一個要求。
None 不重新傳送要求。

如需有關重試原則限制的資訊,請參閱 Logic Apps 限制和設定

變更重試原則

若要選取不同的重試原則,請遵循下列步驟:

  1. 在邏輯應用程式設計工具中開啟邏輯應用程式。

  2. 開啟動作或觸發程序的 [設定]。

  3. 如果動作或觸發程序支援重試原則,請於 [重試原則] 底下選取您想要的類型。

或者,您也可以針對支援重試原則的動作或觸發程序,在其 inputs 區段中手動指定重試原則。 如果您未指定重試原則,則動作會使用預設原則。

"<action-name>": {
   "type": "<action-type>",
   "inputs": {
      "<action-specific-inputs>",
      "retryPolicy": {
         "type": "<retry-policy-type>",
         "interval": "<retry-interval>",
         "count": <retry-attempts>,
         "minimumInterval": "<minimum-interval>",
         "maximumInterval": "<maximum-interval>"
      },
      "<other-action-specific-inputs>"
   },
   "runAfter": {}
}

必要

類型 描述
<重試原則類型> String 您想要使用的重試原則類型:defaultnonefixedexponential
<重試間隔> String 值必須使用 ISO 8601 格式的重試間隔。 預設最小間隔是 PT5S,最大間隔則是 PT1D。 當您使用指數間隔原則時,您可以指定不同的最小和最大值。
<重試次數> 整數 重試次數必須介於 1 到 90 之間

選擇性

類型 描述
<最小間隔> String 對於指數間隔原則,此為隨機選取間隔的最小間隔,且採用 ISO 8601 格式
<最大間隔> String 對於指數間隔原則,此為隨機選取間隔的最大間隔,且採用 ISO 8601 格式

以下是不同原則類型的詳細資訊。

預設

若您未指定重試原則,則動作會使用預設原則 (實際上就是指數間隔原則),此原則會以指數漸增間隔 (以 7.5 秒作調整) 傳送最多四次重試。 間隔的最小值與最大值為 5 秒和 45 秒。

雖然動作或觸發程序中未明確定義,但以下是 HTTP 動作範例中的預設原則行為:

"HTTP": {
   "type": "Http",
   "inputs": {
      "method": "GET",
      "uri": "http://myAPIendpoint/api/action",
      "retryPolicy" : {
         "type": "exponential",
         "interval": "PT7S",
         "count": 4,
         "minimumInterval": "PT5S",
         "maximumInterval": "PT1H"
      }
   },
   "runAfter": {}
}

若要將動作或觸發程序指定為不會重試失敗的要求,請將 設定為 none

固定間隔

若要將動作或觸發程序指定為先等候指定間隔再傳送下一個要求,請將 設定為 fixed

範例

此重試原則會嘗試在第一次失敗要求後再取得最新消息兩次,每次嘗試之間有 30 秒的延遲:

"Get_latest_news": {
   "type": "Http",
   "inputs": {
      "method": "GET",
      "uri": "https://mynews.example.com/latest",
      "retryPolicy": {
         "type": "fixed",
         "interval": "PT30S",
         "count": 2
      }
   }
}

指數間隔

若要將動作或觸發程序指定為先等候隨機間隔再傳送下一個要求,請將 設定為 exponential。 隨機間隔會從指數成長範圍來選取。 (選擇性) 您也可以藉由指定自己的最小和最大間隔,覆寫預設的最小和最大間隔。

隨機變數範圍

此資料表說明 Logic Apps 如何針對每次重試 (最高可達重試次數 (含)),產生指定範圍內的統一隨機變數:

重試數目 最小間隔 最大間隔
1 最大 (0,<最小間隔>) 最小 (間隔,<最大間隔>)
2 最大 (間隔,<最小間隔>) 最小 (2 * 間隔,<最大間隔>)
3 最大 (2 * 間隔,<最小間隔>) 最小 (4 * 間隔,<最大間隔>)
4 最大 (4 * 間隔,<最小間隔>) 最小 (8 * 間隔,<最大間隔>)
.... .... ....

藉由變更「在之後執行」行為來攔截和處理失敗

當您在邏輯應用程式設計工具中新增動作時,您會隱含地宣告用來執行這些動作的順序。 當動作完成執行之後,該動作會標示為、、或等 Succeeded 狀態 Failed Skipped TimedOut 。 在每個動作定義中, runAfter 屬性(property)會指定必須先完成的前置動作,以及在後續動作可執行之前,該前身所允許的狀態。 根據預設,您在設計工具中新增的動作,只會在前置項完成並具有狀態時執行 Succeeded

當動作擲回未處理的錯誤或例外狀況時,會標示該動作 Failed ,並標示任何後續動作 Skipped 。 如果有平行分支的動作發生此行為,Logic Apps 引擎會遵循其他分支,以判斷其完成狀態。 例如,如果分支的結尾是 Skipped 動作,則該分支的完成狀態會以該已略過動作的前置狀態為基礎。 邏輯應用程式執行完成後,引擎會評估所有分支狀態,以判斷整個回合的狀態。 如果任何分支在失敗時結束,則會標示整個邏輯應用程式執行 Failed

示範如何評估執行狀態的範例

若要確定某個動作仍然可以執行(儘管其前身的狀態),請 自訂動作的「執行後執行」行為 ,以處理前身不成功的狀態。

自訂「在之後執行」行為

您可以自訂動作的「執行後執行」行為,以便在前置的狀態為 SucceededFailedSkippedTimedOut 或任一狀態時執行動作。 例如,若要在 Excel Online 前置動作標示之後傳送電子郵件 Add_a_row_into_a_table Failed ,而不是在 Succeeded 下列任一步驟中變更「在之後執行」行為:

  • 在設計檢視中,選取省略號 (...) 按鈕,然後選取 [ 設定執行之後]。

    設定動作的「執行之後」行為

    [動作] 圖形會顯示前置動作所需的預設狀態,也就是在此範例中, 將資料列新增至資料表

    動作的預設「執行之後」行為

    將「執行後執行」行為變更為您想要的狀態,在此範例中為 失敗

    將「執行後執行」行為變更為「已失敗」

    若要指定動作執行,無論前置動作是否標記為 FailedSkippedTimedOut 選取其他狀態:

    將「執行後執行」行為變更為具有任何其他狀態

  • 在程式碼查看中,于動作的 JSON 定義中編輯 runAfter 屬性,其遵循下列語法:

    "<action-name>": {
       "inputs": {
          "<action-specific-inputs>"
       },
       "runAfter": {
          "<preceding-action>": [
             "Succeeded"
          ]
       },
       "type": "<action-type>"
    }
    

    在此範例中,將 runAfter 屬性從變更 SucceededFailed

    "Send_an_email_(V2)": {
       "inputs": {
          "body": {
             "Body": "<p>Failed to&nbsp;add row to &nbsp;@{body('Add_a_row_into_a_table')?['Terms']}</p>",,
             "Subject": "Add row to table failed: @{body('Add_a_row_into_a_table')?['Terms']}",
             "To": "Sophia.Owen@fabrikam.com"
          },
          "host": {
             "connection": {
                "name": "@parameters('$connections')['office365']['connectionId']"
             }
          },
          "method": "post",
          "path": "/v2/Mail"
       },
       "runAfter": {
          "Add_a_row_into_a_table": [
             "Failed"
          ]
       },
       "type": "ApiConnection"
    }
    

    若要指定動作執行,不論前置動作是否標記為 FailedSkippedTimedOut 新增其他狀態:

    "runAfter": {
       "Add_a_row_into_a_table": [
          "Failed", "Skipped", "TimedOut"
       ]
    },
    

以範圍和其結果評估動作

與屬性的個別動作之後的執行步驟類似 runAfter ,您可以在 範圍內將動作群組在一起。 當您想要以邏輯方式將動作群組在一起、評估範圍的彙總狀態,並根據這些狀態執行動作時,即可使用範圍。 當範圍中的所有動作都執行完成之後,範圍本身會取得自己的狀態。

若要檢查範圍的狀態,您可以使用您用來檢查邏輯應用程式執行狀態的相同準則,例如 SucceededFailed 等。

根據預設,當範圍的所有動作都成功時,範圍的狀態會標示為 Succeeded 。 如果範圍中的最後一個動作結果為 FailedAborted ,則範圍的狀態會標示為 Failed

若要在範圍中攔截例外狀況, Failed 並執行處理這些錯誤的動作,您可以使用 runAfterFailed 範圍的屬性。 如此一來,如果範圍中 有任何 動作失敗,而您使用該 runAfter 範圍的屬性,您就可以建立單一動作來攔截失敗。

如需範圍的限制,請參閱限制和設定

取得失敗的內容和結果

雖然從範圍擷取失敗很實用,但還是建議您取得內容以協助解實際上有哪些動作失敗,以及所傳回的任何錯誤或狀態碼。 此函式會接受單一參數(範圍名稱),並傳回包含來自這些第一層級動作之結果的陣列,以傳回範圍動作中最上層 result() 動作的結果。 這些動作物件包含與函數所傳回之屬性相同的屬性 actions() ,例如動作的開始時間、結束時間、狀態、輸入、相互關聯識別碼和輸出。

注意

函式 result() 會傳回第一層動作的結果,而不會傳回更深層的嵌套動作,例如切換或條件動作。

若要取得在某個範圍內失敗之動作的內容,您可以使用 @result() 具有範圍名稱和屬性的運算式 runAfter 。 若要將傳回的陣列向下篩選至具有狀態的動作 Failed ,您可以加入 篩選陣列 動作。 若要針對傳回的失敗動作執行動作,請取得傳回的已篩選陣列,並使用 for each 迴圈

以下是一個範例,後面接著詳細的說明,會傳送 HTTP POST 要求,其中包含在名稱為 "My_Scope" 的範圍動作內失敗之任何動作的回應主體:

"Filter_array": {
   "type": "Query",
   "inputs": {
      "from": "@result('My_Scope')",
      "where": "@equals(item()['status'], 'Failed')"
   },
   "runAfter": {
      "My_Scope": [
         "Failed"
      ]
    }
},
"For_each": {
   "type": "foreach",
   "actions": {
      "Log_exception": {
         "type": "Http",
         "inputs": {
            "method": "POST",
            "body": "@item()['outputs']['body']",
            "headers": {
               "x-failed-action-name": "@item()['name']",
               "x-failed-tracking-id": "@item()['clientTrackingId']"
            },
            "uri": "http://requestb.in/"
         },
         "runAfter": {}
      }
   },
   "foreach": "@body('Filter_array')",
   "runAfter": {
      "Filter_array": [
         "Succeeded"
      ]
   }
}

以下是說明此範例中所發生情況的詳細逐步解說︰

  1. 若要從 "My_Scope" 內的所有動作取得結果,篩選陣列 動作會使用這個篩選條件運算式:@result('My_Scope')

  2. 篩選陣列 的條件是任何 @result() 狀態等於的專案 Failed 。 此條件會將具有 "My_Scope" 所有動作結果的陣列篩選成只剩失敗動作結果的陣列。

  3. For_each篩選的陣列 輸出上執行迴圈動作。 此步驟會對之前篩選的每個失敗動作結果執行動作。

    如果範圍中的單一動作失敗,則迴圈中的動作 For_each 只會執行一次。 如果有多個失敗動作,則會導致對每個失敗執行一個動作。

  4. For_each 專案回應主體(即運算式)上傳送 HTTP POST @item()['outputs']['body']

    @result() 項目圖形和 @actions() 圖形相同,並可透過相同方式剖析。

  5. 包含兩個具有失敗動作名稱 (@item()['name']) 和失敗執行用戶端追蹤識別碼 (@item()['clientTrackingId']) 的自訂標頭。

供您參考,以下範例是單一 @result() 項目,會顯示前一個範例中剖析的 namebodyclientTrackingId 屬性。 在動作之外,會傳回 For_each @result() 這些物件的陣列。

{
   "name": "Example_Action_That_Failed",
   "inputs": {
      "uri": "https://myfailedaction.azurewebsites.net",
      "method": "POST"
   },
   "outputs": {
      "statusCode": 404,
      "headers": {
         "Date": "Thu, 11 Aug 2016 03:18:18 GMT",
         "Server": "Microsoft-IIS/8.0",
         "X-Powered-By": "ASP.NET",
         "Content-Length": "68",
         "Content-Type": "application/json"
      },
      "body": {
         "code": "ResourceNotFound",
         "message": "/docs/folder-name/resource-name does not exist"
      }
   },
   "startTime": "2016-08-11T03:18:19.7755341Z",
   "endTime": "2016-08-11T03:18:20.2598835Z",
   "trackingId": "bdd82e28-ba2c-4160-a700-e3a8f1a38e22",
   "clientTrackingId": "08587307213861835591296330354",
   "code": "NotFound",
   "status": "Failed"
}

若要執行不同的例外狀況處理模式,您可以使用本文前面描述的運算式。 您可以選擇在範圍外執行單一例外狀況處理動作,以接受整個篩選後的失敗陣列,並移除 For_each 動作。 如先前所述,您也可以在回應中包含其他有用的屬性 \@result()

設定 Azure 監視器記錄

上述模式非常適合處理執行內的錯誤和例外狀況,但您也可以識別和回應與執行本身無關的錯誤。 Azure 監視器 提供簡單的方式,將所有工作流程事件(包括所有執行和動作狀態)傳送至 Log Analytics 工作區Azure 儲存體帳戶Azure 事件中樞

若要評估執行狀態,您可以監視記錄和度量,或將它們發佈至您偏好使用的任何監視工具。 其中一個可能的選項是透過「事件中樞」將所有事件串流到 Azure 串流分析。 在「串流分析」中,您可以根據診斷記錄中的任何異常、平均或失敗,撰寫即時查詢。 您可以使用「串流分析」將資訊傳送到其他資料來源,例如傳送到佇列、主題、SQL、Azure Cosmos DB 或 Power BI。

下一步