有什么方法可以延迟 Azure 函数中服务总线消息的重试?
Is there a way I can delay the retry for a service bus message in an Azure function?
我有一个函数可以从订阅中提取消息,并将它们转发到 HTTP 端点。如果端点不可用,则会抛出异常。发生这种情况时,我想将该特定消息的下一次尝试延迟一段时间,例如15分钟。到目前为止,我找到了以下解决方案:
- 捕获异常,睡眠,然后抛出。这是一个糟糕的解决方案,因为我会在它休眠时收取 CPU 使用费,并且会影响函数的吞吐量。
- 捕获异常,克隆消息,设置
ScheduledEnqueueTimeUtc
属性 并将其添加回队列。这是一种更好的方法,但它会重置传递计数,因此实际问题永远不会成为死信,并且当只有一个订阅者未能处理它时,它会重新发送给所有订阅。
- 捕获异常,并将消息放入存储队列。这意味着维护一个存储队列以匹配每个订阅,并且具有两个函数而不是一个函数。
我最希望发生的事情是捕获异常,然后退出函数而不释放对消息的锁定。这样,一旦锁过期,消息将再次重试。但是,似乎在成功完成后,函数在消息上调用Complete()
,抛出异常后,函数在消息上调用Abandon()
。是否可以绕过这个,或者以其他方式实现延迟?
我会通过以下方式解决您的情况,即您提议的流程由 LogicApp 处理比纯函数更好。
在 LogicApp 中实现 wait/retry/dequeue next 模式非常容易,因为这种类型的流控制正是 LogicApps 的设计目标。
虽然仍处于预览阶段(不推荐用于生产代码),但您可以使用 Durable Functions。如果你想保持在代码中操作对象的能力,这可能是你最好的选择!
(也对 LogicApp 解决方案+1!)
这现在通过 retry policies 本机支持,已于 2020 年 11 月左右添加到 Azure Functions(预览版)。您可以将重试策略配置为固定延迟或指数退避。
[FunctionName("MyFunction")]
[FixedDelayRetry(10, "00:15:00")] // retries with a 15-minute delay
public static void Run(
[ServiceBusTrigger("MyTopic", "MySubscription", Connection = "ServiceBusConnection")] string myQueueItem)
{
// Forward message to HTTP endpoint, throwing exception if endpoint unavailable
}
我有一个函数可以从订阅中提取消息,并将它们转发到 HTTP 端点。如果端点不可用,则会抛出异常。发生这种情况时,我想将该特定消息的下一次尝试延迟一段时间,例如15分钟。到目前为止,我找到了以下解决方案:
- 捕获异常,睡眠,然后抛出。这是一个糟糕的解决方案,因为我会在它休眠时收取 CPU 使用费,并且会影响函数的吞吐量。
- 捕获异常,克隆消息,设置
ScheduledEnqueueTimeUtc
属性 并将其添加回队列。这是一种更好的方法,但它会重置传递计数,因此实际问题永远不会成为死信,并且当只有一个订阅者未能处理它时,它会重新发送给所有订阅。 - 捕获异常,并将消息放入存储队列。这意味着维护一个存储队列以匹配每个订阅,并且具有两个函数而不是一个函数。
我最希望发生的事情是捕获异常,然后退出函数而不释放对消息的锁定。这样,一旦锁过期,消息将再次重试。但是,似乎在成功完成后,函数在消息上调用Complete()
,抛出异常后,函数在消息上调用Abandon()
。是否可以绕过这个,或者以其他方式实现延迟?
我会通过以下方式解决您的情况,即您提议的流程由 LogicApp 处理比纯函数更好。
在 LogicApp 中实现 wait/retry/dequeue next 模式非常容易,因为这种类型的流控制正是 LogicApps 的设计目标。
虽然仍处于预览阶段(不推荐用于生产代码),但您可以使用 Durable Functions。如果你想保持在代码中操作对象的能力,这可能是你最好的选择!
(也对 LogicApp 解决方案+1!)
这现在通过 retry policies 本机支持,已于 2020 年 11 月左右添加到 Azure Functions(预览版)。您可以将重试策略配置为固定延迟或指数退避。
[FunctionName("MyFunction")]
[FixedDelayRetry(10, "00:15:00")] // retries with a 15-minute delay
public static void Run(
[ServiceBusTrigger("MyTopic", "MySubscription", Connection = "ServiceBusConnection")] string myQueueItem)
{
// Forward message to HTTP endpoint, throwing exception if endpoint unavailable
}