你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
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 事件中心 | 重试策略 | 函数级 |
Azure 队列存储 | 绑定扩展 | host.json |
RabbitMQ | 绑定扩展 | 死信队列 |
Azure 服务总线 | 绑定扩展 | 死信队列 |
计时器 | 重试策略 | 函数级 |
Kafka | 重试策略 | 函数级 |
重试策略
从 Azure Functions 运行时版本 3.x 开始,可以为 Functions 运行时强制执行的计时器、Kafka、事件中心和 Azure Cosmos DB 触发器定义重试策略。
重试策略指示运行时重新运行失败的执行,直到成功完成或达到最大重试次数。
当计时器、Kafka、事件中心或 Azure Cosmos DB 触发的函数引发未捕获的异常时,会评估重试策略。 最佳做法是捕获代码中的所有异常,并再次引发你想要导致重试的任何错误。
重要
在执行的重试策略完成之前,不会写入事件中心检查点。 由于此行为,在完成当前批次之前,会暂停特定分区上的进度。
对于 Functions 主机与事件中心之间的交互,事件中心 v5 扩展支持其他重试功能。 有关详细信息,请参阅 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”属性 | 说明 |
---|---|
strategy | 必需。 要使用的重试策略。 有效值为 fixedDelay or exponentialBackoff 进行求值的基于 SQL 语言的筛选器表达式。 |
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。 以下文章的“异常和返回代码”部分中提供了与特定于绑定的错误相关的信息: