评价这篇文章

Azure函数提供了基于ServiceBus的触发器绑定,允许我们处理掉到SB队列或交付给SB订阅的消息。在本文中,我们将介绍如何使用ServiceBus触发器创建一个Azure函数,该触发器实现一个可配置的消息重试模式。
注意:本文不是对Azure函数的介绍,也不是对ServiceBus的介绍。对于那些不熟悉这些Azure服务的人,请查看一下Azure文档中心
让我们从创建一个简单的C函数开始,该函数监听发送到sb订阅的消息。
创建azure函数
Azure函数提供了许多方法,我们可以将消息接收到函数中,但为了这篇文章的目的,我们将使用代理消息键入我们想要访问的消息属性。有关通过ServiceBus触发器绑定将消息接收到Azure函数的更多选项,请参阅上述链接。
使用代理消息我们需要进口Microsoft.ServiceBus(服务总线)将输入类型更改为代理消息

如果我们什么都不做,我们的职能部门会收到某人的信息,记录其消息ID并将其从队列中删除。实际上,SB触发器从队列中偷看消息,在过程中获取一个peek锁。如果函数成功执行,消息将从队列中删除。所以当事情变成梨形时会发生什么?让我们加一个梨,观察会发生什么。

注意:要向sb主题发送消息,我使用Paolo Salvatori的ServiceBus浏览器。此工具允许我们查看本文中提到的队列和消息属性。
默认重试
注意函数被多次触发。这将一直持续到sb队列最大交货计数超过了。默认情况下,SB队列和主题有一个最大交货计数10。让我们使用brokeredmessage类的message属性输出函数中的传递计数,这样我们就可以在实际中观察到这一点。

正在输出传递计数
从日志中,我们看到消息重试了10次,直到达到最大传递数,并且ServiceBus超过了消息,发送到死信队列。“啊哈!”,我听到你说。通过配置最大交货计数sb队列或订阅上的属性。好,这很简单,静态重试策略,但通常我们需要一个更可配置的,动态方法。一种基于处理逻辑捕获的消息上下文或异常类型的异常。
典型的用例包括处理业务错误(例如消息验证错误,下游处理错误等)与运输错误(如下游服务不可用,请求超时等)。在处理业务错误时,我们可以选择不重试失败的消息,而是将其移动到死信队列。在处理传输错误时,我们可能希望处理瞬时故障(例如数据库连接)和协议错误(例如503服务不可用)不同。暂时故障我们可能希望在短时间内重试几次,作为协议错误,我们可能希望在较长时间内继续尝试服务。
要实现此功能,我们将创建一个共享函数,该函数根据抛出的异常的上下文确定适当的重试策略。然后,它将根据策略定义的最大值检查重试次数。如果超过了重试次数,消息被移动到死信队列,否则,函数将等待策略定义的持续时间,然后抛出原始异常。

让我们更改函数以抛出模拟异常,并调用重试处理函数来实现消息重试策略。

现在,我们的函数实现一些基本的异常处理,并检查是否要使用适当的重试策略。让我们通过抛出策略支持的不同异常来测试重试策略的工作情况。
测试抛出我们的模拟业务规则异常…
测试模拟业务异常
…我们观察到消息按照我们定义的策略直接移动到死信队列。
正在测试引发模拟协议异常…测试模拟协议异常
我们观察到我们总共重试了5次信息,根据定义的协议错误策略,在两次重试之间等待3秒。
注意事项

  • 确保使用最大交货计数大于最大重试次数。
  • 确保您的SB队列和订阅定义的TTL周期大于最大重试间隔。
  • 请注意,使用基于消耗的服务计划的最大执行时间为5分钟。应用程序服务计划没有这个限制。然而,确保functionTimeout设置在主机.json文件大于您的最大重试间隔。
  • 还要注意,如果您使用基于消耗的计划,您仍然需要为等待重试间隔(线程睡眠)所花费的时间付费。

结论
在本文中,我们探讨了ServiceBus触发器绑定在Azure函数中的行为,以及如何实现动态消息重试策略。只要您愿意自己管理消息内容的反序列化(而不是让Azure函数为您完成),您就可以访问代理消息类并在Azure平台上实现功能丰富的消息传递解决方案。

类别:
Azure平台
标签:

加入对话!2的评论

  1. 我看到您在函数中使用Azure服务总线触发器使其成为事件驱动的。事件驱动模式的一个缺点是重播功能。例如,如果Azure函数有中断,并且如果10分钟后返回,它会处理在该中断期间服务总线中累积的消息吗?

    回复
  2. 很难相信在Azure函数末尾添加thread.sleep()是最佳实践…

    回复

留下答复