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 套件支援函式層級重試:
- Microsoft.Azure.Functions.Worker.Sdk>= 1.9.0
- Microsoft.Azure.Functions.Worker.Extensions.EventHubs>= 5.2.0
- Microsoft.Azure.Functions.Worker.Extensions.Kafka>= 3.8.0
- Microsoft.Azure.Functions.Worker.Extensions.Timer>= 4.2.0
[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 屬性 | 描述 |
---|---|
策略 | 必要。 要使用的重試策略。 有效值為 fixedDelay 或 exponentialBackoff 。 |
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。 下列文章的<例外狀況和傳回碼>一節提供繫結特定錯誤的相關資訊: