Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 有没有办法延迟Azure函数中服务总线消息的重试?_C#_Azure Functions_Servicebus_Azure Servicebus Topics_Retry Logic - Fatal编程技术网

C# 有没有办法延迟Azure函数中服务总线消息的重试?

C# 有没有办法延迟Azure函数中服务总线消息的重试?,c#,azure-functions,servicebus,azure-servicebus-topics,retry-logic,C#,Azure Functions,Servicebus,Azure Servicebus Topics,Retry Logic,我有一个函数,可以从订阅中提取消息,并将它们转发到HTTP端点。如果端点不可用,将引发异常。发生这种情况时,我希望将该特定消息的下一次尝试延迟一定时间,例如15分钟。到目前为止,我找到了以下解决方案: 捕获异常,睡眠,然后抛出。这是一个糟糕的解决方案,因为在它睡眠时,我将收取CPU使用费,这将影响函数的吞吐量 捕获异常,克隆消息,设置scheduledQueueTimeUTC属性并将其添加回队列。这是一种更好的方法,但它会重置传递计数,因此实际问题永远不会是死信,并且当只有一个订阅者无法处理它

我有一个函数,可以从订阅中提取消息,并将它们转发到HTTP端点。如果端点不可用,将引发异常。发生这种情况时,我希望将该特定消息的下一次尝试延迟一定时间,例如15分钟。到目前为止,我找到了以下解决方案:

  • 捕获异常,睡眠,然后抛出。这是一个糟糕的解决方案,因为在它睡眠时,我将收取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
返回代码。现在我需要弄清楚如何为授权头和消息体提取代理消息的部分内容