c# - 如何在 Azure Functions 中实现指数退避?
问题描述
如何在 Azure Functions 中实现指数退避?
我有一个依赖于外部 API 的函数。我想使用重试策略来处理此服务的不可用性。当队列中出现新消息时触发此功能,在这种情况下,此策略默认打开:
对于大多数触发器,在函数执行期间发生错误时没有内置的重试。支持重试的两个触发器是 Azure 队列存储和 Azure Blob 存储。默认情况下,这些触发器最多重试五次。在第五次重试之后,两个触发器都将消息写入一个特殊的毒物队列。
不幸的是,重试在异常 (TimeSpan.Zero) 之后立即开始,在这种情况下这是没有意义的,因为服务很可能仍然不可用。 有没有办法动态修改消息在队列中再次可用的时间?
我知道我可以设置visibilityTimeout
(host.json 参考),但它是为所有队列设置的,这不是我想要在这里实现的。
我找到了一种解决方法,但它远非理想的解决方案。如果出现异常,我们可以再次将消息添加到队列中,并为此消息设置 visibilityTimeout:
[FunctionName("Test")]
public static async Task Run([QueueTrigger("queue-test")]string myQueueItem, TraceWriter log,
ExecutionContext context, [Queue("queue-test")] CloudQueue outputQueue)
{
if (true)
{
log.Error("Error message");
await outputQueue.AddMessageAsync(new CloudQueueMessage(myQueueItem), TimeSpan.FromDays(7),
TimeSpan.FromMinutes(1), // <-- visibilityTimeout
null, null).ConfigureAwait(false);
return;
}
}
不幸的是,这个解决方案很弱,因为它没有上下文(我不知道它是哪种尝试,因此我不能限制调用次数并修改时间(指数退避))。
内部重试策略也不受欢迎,因为它会大大增加成本(定价模型)。
解决方案
微软在 2020 年 11 月左右(预览版)添加了重试策略,支持指数退避:
[FunctionName("Test")]
[ExponentialBackoffRetry(5, "00:00:04", "00:15:00")] // retries with delays increasing from 4 seconds to 15 minutes
public static async Task Run([QueueTrigger("queue-test")]string myQueueItem, TraceWriter log, ExecutionContext context)
{
// ...
}
推荐阅读
- google-cloud-platform - Google Cloud Platform Pub Sub - Python 客户端不发布消息
- python - 在 Python 中使用 StatsModels 运行 GLM
- android - 我需要 scaleType="matrix" 以便在 ImageView 中拖动对象。我希望使用默认的 fit_center 使图像更小
- php - 在 PHP MYSQLI 中将 3 个或更多表链接在一起以创建墙提要
- webpack - 使用 mode 和 webpack.EnvironmentPlugin 是多余的吗?
- wordpress - 如何在没有wordpress页面的情况下重定向wp过去的网站
- c# - 我应该在哪里调用 C#.NET 中不兼容类型转换的打印函数?
- wordpress - Local By Flywheel - 建立数据库连接时出错
- python - 如何格式化Django表单中选择字段中的选择标签?
- python - 保持一致的 matplotlib 轴限制