C# 有没有办法延迟Azure函数中服务总线消息的重试?
我有一个函数,可以从订阅中提取消息,并将它们转发到HTTP端点。如果端点不可用,将引发异常。发生这种情况时,我希望将该特定消息的下一次尝试延迟一定时间,例如15分钟。到目前为止,我找到了以下解决方案:C# 有没有办法延迟Azure函数中服务总线消息的重试?,c#,azure-functions,servicebus,azure-servicebus-topics,retry-logic,C#,Azure Functions,Servicebus,Azure Servicebus Topics,Retry Logic,我有一个函数,可以从订阅中提取消息,并将它们转发到HTTP端点。如果端点不可用,将引发异常。发生这种情况时,我希望将该特定消息的下一次尝试延迟一定时间,例如15分钟。到目前为止,我找到了以下解决方案: 捕获异常,睡眠,然后抛出。这是一个糟糕的解决方案,因为在它睡眠时,我将收取CPU使用费,这将影响函数的吞吐量 捕获异常,克隆消息,设置scheduledQueueTimeUTC属性并将其添加回队列。这是一种更好的方法,但它会重置传递计数,因此实际问题永远不会是死信,并且当只有一个订阅者无法处理它
- 捕获异常,睡眠,然后抛出。这是一个糟糕的解决方案,因为在它睡眠时,我将收取CPU使用费,这将影响函数的吞吐量
- 捕获异常,克隆消息,设置
属性并将其添加回队列。这是一种更好的方法,但它会重置传递计数,因此实际问题永远不会是死信,并且当只有一个订阅者无法处理它时,它会重新发送给所有订阅者scheduledQueueTimeUTC
- 捕获异常,并将消息放在存储队列上。这意味着维护一个存储队列以匹配每个订阅,并具有两个功能,而不是一个
理想情况下,我希望捕获异常,并在不释放消息锁的情况下退出函数。这样,一旦锁过期,消息将再次重试。但是,似乎在成功完成后,函数会调用消息上的
Complete()
,在抛出异常后,函数会调用消息上的放弃()
。有没有可能绕过这一点,或者以其他方式实现延迟?我将通过以下方式来解决您的情况:LogicApp比纯函数更好地处理您提议的流
在LogicApp中实现wait/retry/dequeue next模式非常容易,因为这种类型的流控制正是LogicApp设计的目的。尽管仍处于预览阶段(不建议用于生产代码),但您可以使用。如果您想保持在代码中操作对象的能力,这可能是您的最佳选择
(+1也适用于LogicApp解决方案!)这现在通过本机支持,并在2020年11月左右添加到Azure功能中(预览版)。您可以将重试策略配置为固定延迟或指数退避
[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
}
如果这些异常不经常发生,您可以创建一个带有计时器的函数,该计时器每15分钟启动一次,并检查死信队列。是的,考虑到它们有一个
HTTP
操作,允许您在408
上定义重试策略,这显然更像我想要的,429
和5XX
返回代码。现在我需要弄清楚如何为授权头和消息体提取代理消息的部分内容