2016-09-22 81 views
4

我正在使用在存储队列上有新消息时触发的Azure功能(用C#编写)。该功能正在调用外部Web服务来处理消息,并且当外部服务响应时,一切正常。如何在失败后延迟Azure功能的执行?

问题是当外部网站关闭时,web客户端发出异常(没有围绕它的try/catch块)。接下来会发生的事情是该函数被重试(通过天蓝色)5次,每次尝试之间不到1秒。正如你可以想象的那样,Web服务可能仍然会关闭所有5次尝试,这将使Azure将消息转移到“毒药”队列。

是否可以配置重试之前等待的时间量,还是需要设置另一个每分钟运行一次的azure函数来检查消息的毒性队列,然后需要在正常队列?

回答

0

该函数调用外部Web服务来处理消息,并且当外部服务响应时,一切正常。

为什么不用信号通知队列消息的服务状态。

Function is triggered 
     \/
     \/ 
Do we have a message in service-status queue? 
     \/
     \/  
Wait 30 seconds before making web-service call/else call it right away. 
     \/
     \/ 
Can't reach web-service? -> Drop message in service-status queue. 

如果你有你需要对存储或任一个持久文件表存储的条目以通知功能应用程序的多个实例。

+0

感谢您的快速回复,这个想法很好。然而,问题在于Azure第二次收到这些函数,因此在它内部运行Thread.Sleep(30000)将会非常昂贵。 – Espo

+0

然后不要等待30秒。放弃。你不会删除它,因为你没有删除它。它会在'visibility_timeout'中再次显示。队列中的消息顺序将被拧紧,但如果你能容忍,我没有看到任何其他缺点。 – evilSnobu

+0

也许我误解了你,但是如果我刚刚退出这个功能,azure会认为这个消息已经成功处理了,并且它将永远消失。我还没有发现如何从azure函数中更改/设置visibility-timeout。 – Espo

4

我们目前不公开一种方式来配置失败消息的可见性超时。正如你所注意到的,它目前被编码为TimeSpan.Zero。我同意你的意见,我们应该允许这个定制。我已在我们的公开回购中记录了一个问题,其中有更多详细信息here

+0

感谢您创建此问题。你说了一些关于创建自定义队列处理器的内容,但我想这只适用于webjobs而不是azure功能? – Espo

+0

是的,这是一个更复杂,更低级别的自定义功能,在函数中不可用。 – mathewc

0

我们最终处理了visibilityTimeout参数“手动”:我们不使用输出绑定,而是将队列中的消息安排在队列中供以后使用Azure存储SDK进行处理。

https://github.com/teamdigitale/digital-citizenship-functions/blob/master/lib/utils/azure_queues.ts#L86

queueService.updateMessage(
     queueName, 
     queueMessage.id, 
     queueMessage.popReceipt, 
     visibilityTimeoutSec, 
     err => { 
      context.done(err); 
     } 
    ); 

这让我们塞reties指数退避策略,而无需把进程进入休眠状态。