问题描述
我想在我的 Azure Function 中实现一个非常简单的行为:如果在处理过程中出现异常,我想将下一次重试推迟一段时间。据我所知,在服务总线中没有直接的可能性,例如(除非创建一条新消息),但服务总线触发器有可能ExponentialBackoffRetry
。
我没有找到任何关于服务总线连接如何工作的文档。 IE。函数执行失败后消息会发生什么。
一种可能的方法是将消息保留在函数基础结构中,并在我想的持续时间内不断更新锁。关于我想知道的一些更实际的问题:
- 我可以使用退避重试多长时间(例如,如果我想重试最多 7 天,例如这会起作用吗?)
- 当主机被重置/重新启动/缩放时会发生什么,我是否会因为实现细节而失去这种退避,或者它仍然以某种方式得到维护?
解决方法
重试选项适用于服务总线 SDK 执行的单个服务操作,旨在让 SDK 解决短期暂时性问题,例如偶尔的网络中断。除了配置 SDK 客户端之外,Functions 基础架构不知道重试,只会看到 SDK 花费更长的时间来执行请求的读取/发布操作。
Functions 基础设施将应用由运行时强加的任何执行时间限制,或者可能决定采取措施来防止无响应的服务操作。 (免责声明:我可以使用 Service Bus SDK,但对 Functions 运行时没有深入了解)
来自服务总线扩展的重试不适用于您的函数代码;如果您的代码出现错误,您最终会遇到异常情况,并且根据配置和触发器/绑定使用情况,您可能会看到消息被放弃或锁定一直保持到超时。
我不确定您的确切情况,但您似乎需要考虑 deferring 稍后显式读取消息,或者使用 schedule 重新排队消息以便函数可以在未来的特定时间点再次读取。
,在触发器弹性之上使用重试支持
函数应用重试策略独立于触发器提供的任何重试或弹性。函数重试策略只会在触发弹性重试之上。例如,如果使用 Azure 服务总线,默认情况下队列的消息传递计数为 10。默认传递计数意味着在尝试传递队列消息 10 次后,服务总线将对消息进行死信处理。您可以为具有服务总线触发器的函数定义重试策略,但重试将叠加在服务总线交付尝试之上。
例如,如果您使用默认的服务总线交付计数 10,并定义函数重试策略 5。消息将首先出队,将服务总线交付帐户增加到 1。如果每次执行失败,则在尝试五次后要触发相同的消息,该消息将被标记为已放弃。服务总线会立即重新排队消息,它会触发该函数并将传递计数增加到 2。最后,在 50 次最终尝试(10 次服务总线传递 * 每次传递 5 次函数重试)后,该消息将被放弃并触发死机 -服务巴士上的信。
对于指数重试,您可能需要将总退避时间 + 处理保持在小于函数可以保留消息的时间,否则锁将过期,即使成功处理也会导致异常并重试。
如今服务总线锁定消息的方式,基于 Azure 服务总线的指数退避并不是一个好主意。一旦可以使用持久终端(无限锁定时间,无需更新),这将更有意义。