Azure Functions 錯誤處理和重試

處理 Azure Functions 中的錯誤十分重要,可協助您避免遺失資料、避免遺漏事件以及監視應用程式的健康情況。 這也是協助您了解事件型觸發程序的重試行為的重要方式。

本文說明錯誤處理和可用重試策略的一般策略。

重要

此功能正式發行 (GA) 之後,將移除計時器、Kafka 和事件中樞以外的觸發程序執行階段重試原則支援。 計時器和事件中樞以外的所有觸發程序的預覽重試原則支援已於 2022 年 12 月移除。 如需詳細資訊,請參閱重新嘗試一節。

處理錯誤

Azure 函式中發生的錯誤可能是下列任何一項所造成:

  • 使用內建 Azure Functions 觸發程序與繫結
  • 呼叫基礎 Azure 服務的 API
  • 呼叫 REST 端點
  • 呼叫用戶端程式庫、套件或協力廠商 API

若要避免遺失資料或遺漏訊息,良好的錯誤處理做法十分重要。 本節描述一些建議錯誤處理做法並提供詳細資訊的連結。

啟用 Application Insights

Azure Functions 與 Application Insights 整合,以收集錯誤資料、效能資料和執行階段記錄。 您應該使用 Application Insights 來探索並進一步了解函式執行中發生的錯誤。 若要深入了解,請參閱監視 Azure Functions

使用結構化錯誤處理

擷取及記錄錯誤對於監視應用程式的健康狀態至關重要。 任何函式程式碼的最上層都應該包含 try/catch 區塊。 在 catch 區塊中,您可以擷取及記錄錯誤。 如需繫結可能引發哪些錯誤的相關資訊,請參閱繫結錯誤碼

規劃重試策略

數個 Functions 繫結延伸模組提供內建重試支援。 此外,執行階段可讓您定義計時器、Kafka 和事件中樞觸發函式的重試原則。 若要深入了解,請參閱重試。 針對未提供重試行為的觸發程序,您可能會想要實作自己的重試配置。

冪等性的設計

處理資料時發生錯誤可能是函式的問題,特別是在處理訊息時。 務必考慮發生錯誤時會發生什麼情況,以及如何避免重複處理。 若要深入了解,請參閱設計相同輸入的 Azure Functions

重試

函式有兩種可用的重試:

  • 個別觸發程序延伸模組的內建重試行為
  • Functions 執行階段提供的重試原則

下表指出哪些觸發程序支援重試,以及設定重試行為的位置。 它也會連結至來自基礎服務的錯誤詳細資訊。

觸發程序/繫結 重試來源 組態
Azure Cosmos DB 重試原則 函數層級
Azure Blob 儲存體 繫結延伸模組 host.json
事件格線 繫結延伸模組 事件訂閱
Azure 事件中樞 重試原則 函數層級
Azure 佇列儲存體 繫結延伸模組 host.json
RabbitMQ 繫結延伸模組 無效信件佇列
Azure 服務匯流排 繫結延伸模組 無效信件佇列
計時器 重試原則 函數層級
Kafka 重試原則 函數層級

重試原則

從 Azure Functions 執行階段 3.x 版開始,您可以針對 Functions 執行階段所強制執行的計時器、Kafka、事件中樞和 Azure Cosmos DB 觸發程序定義重試原則。

除非成功完成或達到重試次數上限,否則重試原則會告知執行階段重新執行失敗的執行。

計時器、Kafka、事件中樞或 Azure Cosmos DB 觸發的函式引發未攔截的例外狀況時,重試原則會受到評估。 最佳做法是,您應該攔截程式碼中的所有例外狀況,並重新擲回任何想要導致重試的錯誤。

重要

除非執行的重試原則已完成,否則不會寫入事件中樞檢查點。 因為此行為,所以除非目前的批次已完成,否則特定分割區的進度會暫停。

事件中樞 v5 延伸模組支援其他重試功能,以用於 Functions 主機與事件中樞之間的互動。 如需詳細資訊,請參閱 host.json 檔案的事件中樞一節中的 clientRetryOptions

重試策略

您可以設定原則支援的兩個重試策略:

允許在每次重試之間經過指定的時間量。

重試計數上限

您可以設定在最終失敗前重試函式執行的次數上限。 目前的重試計數會儲存於執行個體的記憶體中。

執行個體在重試嘗試之間可能會失敗。 當執行個體在重試原則期間失敗時,重試計數就會遺失。 發生執行個體失敗時,事件中樞觸發程序能夠繼續處理,並在新的執行個體上重試批次,並將重試計數重設為零。 計時器觸發程序不會在新執行個體上繼續。

此行為表示重試計數上限是最佳數量。 在某些情況下,執行可能會重試超過要求次數的上限。 針對計時器觸發程序,重試可以小於要求的次數上限。

重試範例

下列 NuGet 套件支援函式層級重試:

[Function(nameof(TimerFunction))]
[FixedDelayRetry(5, "00:00:10")]
public static void Run([TimerTrigger("0 */5 * * * *")] TimerInfo timerInfo,
    FunctionContext context)
{
    var logger = context.GetLogger(nameof(TimerFunction));
    logger.LogInformation($"Function Ran. Next timer schedule = {timerInfo.ScheduleStatus.Next}");
}
屬性 說明
MaxRetryCount 必要。 每個函式執行允許的重試次數上限。 -1 表示無限期重試。
DelayInterval 重試之間所使用的延遲。 將其指定為格式 HH:mm:ss 的字串。

以下是 function.json 檔案中的重試原則:

{
    "disabled": false,
    "bindings": [
        {
            ....
        }
    ],
    "retry": {
        "strategy": "fixedDelay",
        "maxRetryCount": 4,
        "delayInterval": "00:00:10"
    }
}
function.json 屬性 描述
策略 必要。 要使用的重試策略。 有效值為 fixedDelayexponentialBackoff
maxRetryCount 必要。 每個函式執行允許的重試次數上限。 -1 表示無限期重試。
delayInterval 使用 fixedDelay 策略時,重試之間使用的延遲。 將其指定為格式 HH:mm:ss 的字串。
minimumInterval 使用 exponentialBackoff 策略時的重試延遲下限。 將其指定為格式 HH:mm:ss 的字串。
maximumInterval 使用 exponentialBackoff 策略時的重試延遲上限。 將其指定為格式 HH:mm:ss 的字串。

以下是在函式中使用重試內容的 Python 範例:

import azure.functions
import logging


def main(mytimer: azure.functions.TimerRequest, context: azure.functions.Context) -> None:
    logging.info(f'Current retry count: {context.retry_context.retry_count}')

    if context.retry_context.retry_count == context.retry_context.max_retry_count:
        logging.warn(
            f"Max retries of {context.retry_context.max_retry_count} for "
            f"function {context.function_name} has been reached")

@FunctionName("TimerTriggerJava1")
@FixedDelayRetry(maxRetryCount = 4, delayInterval = "00:00:10")
public void run(
    @TimerTrigger(name = "timerInfo", schedule = "0 */5 * * * *") String timerInfo,
    final ExecutionContext context
) {
    context.getLogger().info("Java Timer trigger function executed at: " + LocalDateTime.now());
}

繫結錯誤碼

在與 Azure 服務整合時,錯誤可能會來自基礎服務的 API。 下列文章的<例外狀況和傳回碼>一節提供繫結特定錯誤的相關資訊:

下一步