我目前正在评估使用服务总线和 azure 函数来触发一些需要通过下游 API 调用完成的工作。这一切都是相当标准的,除了我没有很好地处理当下游系统过载和/或将 header 返回到 throttle 时会发生什么(即每分钟最大调用数/等)。我们似乎没有对队列触发器的强制限制进行任何动态控制。
我知道我们可以手动设置max concurrency但这并不一定能解决问题,因为我们无法控制下游系统,并且需要考虑它随时可能离线或缓慢。
此外,我们可以创建消息,以便它们计划以一定的速率流入,但下游系统仍然可能饱和或返回速率限制。
选项 1:
假设消费计划,从解决方案的角度来看,这是我能想到的一种方法:
- 队列1 - 全速或最大速度。如果我们开始受到速率限制,请设置一个缓存值。如果设置了缓存值,则不处理该消息,克隆它并放入queue2
- Queue2 - 每个最大并发/预取计数较低。与上面的过程相同,但插入队列3。
- Queue3 - 每个最大并发/预取计数的最低值。我们只是慢慢地处理它们。
基本上,当下游系统饱和时,队列 1 成为队列 2 和队列 3 的 Controller 。
选项 2:
我们可以克隆消息并在将来将其重新排队,并继续这样做,直到它们都是进程。保留一个队列并重新排队,直到我们处理它。
选项 3:
假设我们有自己的应用程序计划,该计划是专用的而不是消耗的,我想我们可以Thread.Sleep
函数,如果它们接近速率限制或下降并继续重试。这可能是最大并发数、实例和速率限制的计算。我不会在消费计划中考虑这一点,因为 sleep 可能会大幅增加成本。
我想知道我是否缺少一些简单的方法来处理下游饱和或限制队列触发器(可能是服务总线或存储队列)的最佳方式
编辑: 我想补充一点,我将 100 万条消息注入(inject)到发送时安排的服务总线队列中。我观察到 Azure Function(消耗计划)规模达到了大约 1500/秒,这提供了一个很好的指标。我还不确定那些专注的人会表现如何。
看起来主机文件可以即时修改并且设置立即生效。虽然这适用于所有功能,但它可能适用于我的特定情况(更新设置并每隔一分钟左右再次检查一次,具体取决于速率限制)。
This看起来,当功能团队实现时,这可能是朝着正确方向迈出的一步,但即便如此,我们仍然需要一种方法来管理下游错误。
最佳答案
不幸的是,服务总线触发器(以及更普遍的 Azure Functions)目前无法提供您所需的反压功能,因此您需要自己处理。
您描述的方法是可行的,您只需要在不同的函数应用程序中处理该方法,因为服务总线设置适用于整个应用程序而不仅仅是一个函数。
在您的场景中可能没有太大帮助,但对于处理队列 2 或 3 的应用,您还可以尝试使用预览标志来限制应用的横向扩展实例数量:WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT
.请注意,这是预览版,尚不能保证。
我鼓励您在 functions repo 上提出问题记录您的场景。这类问题绝对是我们想要解决的问题,我们收到的反馈越多越好。
关于Azure Function - 限制服务总线触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44244324/