分享方式:


Azure Functions 錯誤處理和重試

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

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

重要

2022 年 12 月已移除特定觸發程式的預覽重試原則支援。 支持的觸發程式的重試原則現已正式推出(GA)。 如需目前支援重試原則的延伸模塊清單,請參閱 重試 一節。

處理錯誤

Azure 函式中發生的錯誤可能來自:

  • 使用內建的 Functions 觸發程式和系結。
  • 呼叫基礎 Azure 服務的 API。
  • 呼叫 REST 端點。
  • 呼叫客戶端連結庫、套件或第三方 API。

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

建議 詳細資料
啟用 Application Insights Azure Functions 與 Application Insights 整合,以收集錯誤資料、效能資料和執行階段記錄。 您應該使用 Application Insights 來探索並進一步了解函式執行中發生的錯誤。 若要深入了解,請參閱監視 Azure Functions
使用結構化錯誤處理 擷取及記錄錯誤對於監視應用程式的健康狀態至關重要。 任何函式程式碼的最上層都應該包含 try/catch 區塊。 在 catch 區塊中,您可以擷取及記錄錯誤。 如需繫結可能引發哪些錯誤的相關資訊,請參閱繫結錯誤碼。 視您的特定重試策略而定,您可能也會引發新的例外狀況,再次執行函式。
規劃重試策略 數個 Functions 系結延伸模組提供重試的內建支援,而其他函式則可讓您定義 Functions 運行時間所實作的重試原則。 對於未提供重試行為的觸發程式,您應該考慮實作自己的重試配置。 如需詳細資訊,請參閱 重試
設計等冪性 處理資料時發生錯誤可能是函式的問題,特別是在處理訊息時。 務必考慮發生錯誤時會發生什麼情況,以及如何避免重複處理。 若要深入了解,請參閱設計相同輸入的 Azure Functions

重試

函式有兩種可用的重試:

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

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

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

*需要 5.x 版的 Azure 服務匯流排 擴充功能。 在舊版擴充功能中,重試行為是由寄不出的信件佇列 服務匯流排 實作。

重試原則

Azure Functions 可讓您為運行時間強制執行的特定觸發程式類型定義重試原則。 這些觸發程式類型目前支援重試原則:

v1 和 v2 Python 程式設計模型的重試支援都相同。

Functions 運行時間 1.x 版不支援重試原則。

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

當支援的觸發程式類型執行的函式引發未攔截的例外狀況時,就會評估重試原則。 最佳做法是,您應該攔截程序代碼中的所有例外狀況,並針對您想要重試的任何錯誤引發新的例外狀況。

重要

在執行重試原則完成之前,不會寫入事件中樞檢查點。 由於此行為,特定分割區的進度會暫停,直到目前批次完成處理為止。

事件中樞擴充功能 5.x 版支援 Functions 主機與事件中樞之間互動的其他重試功能。 如需詳細資訊,請參閱 clientRetryOptions 事件中 樞host.json參考

重試策略

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

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

在取用方案中執行時,您只需支付函式程式代碼執行的時間。 在上述任一重試策略中,執行之間的等候時間不會向您收取費用。

重試計數上限

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

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

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

重試範例

提供固定延遲和指數輪詢策略的範例。 若要查看特定策略的範例,您必須先在上一個索引標籤中選取該策略。

下列 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"
    }
}

您可以在重試原則定義上設定這些屬性:

屬性 說明
策略 必要。 要使用的重試策略。 有效值為 fixedDelayexponentialBackoff
maxRetryCount 必要。 每個函式執行允許的重試次數上限。 -1 表示無限期重試。
delayInterval 當您使用 fixedDelay 策略時,重試之間所使用的延遲。 將其指定為格式 HH:mm:ss 的字串。
minimumInterval 使用 exponentialBackoff 策略時的重試延遲下限。 將其指定為格式 HH:mm:ss 的字串。
maximumInterval 使用 exponentialBackoff 策略時的重試延遲上限。 將其指定為格式 HH:mm:ss 的字串。

您為觸發程式定義重試原則的方式取決於您的Node.js版本。

以下是使用固定延遲重試策略的定時器觸發程式函式範例:

const { app } = require('@azure/functions');

app.timer('timerTriggerWithRetry', {
    schedule: '0 */5 * * * *',
    retry: {
        strategy: 'fixedDelay',
        delayInterval: {
            seconds: 10,
        },
        maxRetryCount: 4,
    },
    handler: (myTimer, context) => {
        if (context.retryContext?.retryCount < 2) {
            throw new Error('Retry!');
        } else {
            context.log('Timer function processed request.');
        }
    },
});

您為觸發程式定義重試原則的方式取決於您的Node.js版本。

以下是使用固定延遲重試策略的定時器觸發程式函式範例:

import { app, InvocationContext, Timer } from '@azure/functions';

export async function timerTriggerWithRetry(myTimer: Timer, context: InvocationContext): Promise<void> {
    if (context.retryContext?.retryCount < 2) {
        throw new Error('Retry!');
    } else {
        context.log('Timer function processed request.');
    }
}

app.timer('timerTriggerWithRetry', {
    schedule: '0 */5 * * * *',
    retry: {
        strategy: 'fixedDelay',
        delayInterval: {
            seconds: 10,
        },
        maxRetryCount: 4,
    },
    handler: timerTriggerWithRetry,
});

您可以在重試原則定義上設定這些屬性:

屬性 說明
策略 必要。 要使用的重試策略。 有效值為 fixedDelayexponentialBackoff
maxRetryCount 必要。 每個函式執行允許的重試次數上限。 -1 表示無限期重試。
delayInterval 當您使用 fixedDelay 策略時,重試之間所使用的延遲。 將其指定為格式 HH:mm:ss 的字串。
minimumInterval 使用 exponentialBackoff 策略時的重試延遲下限。 將其指定為格式 HH:mm:ss 的字串。
maximumInterval 使用 exponentialBackoff 策略時的重試延遲上限。 將其指定為格式 HH:mm:ss 的字串。

以下是使用固定延遲重試策略的定時器觸發程式函式範例:

import logging

from azure.functions import AuthLevel, Context, FunctionApp, TimerRequest

app = FunctionApp(http_auth_level=AuthLevel.ANONYMOUS)


@app.timer_trigger(schedule="*/1 * * * * *", arg_name="mytimer",
                   run_on_startup=False,
                   use_monitor=False)
@app.retry(strategy="fixed_delay", max_retry_count="3",
           delay_interval="00:00:01")
def mytimer(mytimer: TimerRequest, context: 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.info(
            f"Max retries of {context.retry_context.max_retry_count} for "
            f"function {context.function_name} has been reached")
    else:
        raise Exception("This is a retryable exception")

您可以在重試原則定義上設定這些屬性:

屬性 說明
策略 必要。 要使用的重試策略。 有效值為 fixed_delayexponential_backoff
max_retry_count 必要。 每個函式執行允許的重試次數上限。 -1 表示無限期重試。
delay_interval 當您使用 fixed_delay 策略時,重試之間所使用的延遲。 將其指定為格式 HH:mm:ss 的字串。
minimum_interval 使用 exponential_backoff 策略時的重試延遲下限。 將其指定為格式 HH:mm:ss 的字串。
maximum_interval 使用 exponential_backoff 策略時的重試延遲上限。 將其指定為格式 HH:mm:ss 的字串。
@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。 下列文章的<例外狀況和傳回碼>一節提供繫結特定錯誤的相關資訊:

下一步