Azure Functions - 限制服务总线触发
Azure Function - Throttle the Service bus triggering
我目前正在评估使用服务总线和 azure 函数来触发一些需要通过下游 api 调用完成的工作。这一切都是非常标准的,除了我没有很好地处理下游系统过载时发生的事情 and/or 是 returning headers 以节流(即,每个 [=56 的最大调用数=]).我们似乎对队列触发器的强制节流没有任何动态控制。
我知道我们可以手动设置 max concurrency 但这并不一定能解决问题,因为我们无法控制下游系统并且需要考虑它可能会离线或变慢时间.
此外,我们可以创建消息,以便安排它们以特定速率流入,但下游系统仍然可以饱和或 return 速率限制。
选项 1:
假设消费计划,从解决方案的角度来看,这是我能想到的一种方式:
- Queue1 - 全速或最大速度。如果我们开始获得速率限制,请设置一个缓存值。如果设置了缓存值,则不处理该消息,将其克隆并放入queue2
- Queue2 - 低于最大 concurrency/prefetch 计数。与上述过程相同,但推入队列 3。
- Queue3 - 每个最大 concurrency/prefetch 计数最低。我们只是慢慢处理它们。
基本上,当下游系统饱和时,队列 1 成为队列 2 和队列 3 的控制器。
选项 2:
我们可以克隆消息并在将来重新排队,并继续这样做,直到它们都是进程。保留一个队列并重新排队直到我们处理它。
选项 3:
假设我们有自己的专用而不是消费的应用程序计划,我想我们可以 Thread.Sleep
如果函数接近速率限制或下降并继续重试。这可能是最大并发、实例和速率限制的计算。我不会在消费计划中考虑这一点,因为睡眠会大大增加成本。
我想知道我是否遗漏了处理下游饱和或限制队列触发器(可能是服务总线或存储队列)的最佳方式的简单方法
编辑:
我想补充一点,我将 100 万条消息发送到在发送时间安排的服务总线队列中。我观察到 Azure Function(消费计划)规模达到大约 1500/秒以提供一个很好的指标。我不确定专用的性能如何。
看来可以即时修改主机文件,设置立即生效。虽然这适用于所有功能,但它可能适用于我的特定情况(更新设置并根据速率限制每分钟左右再次检查一次)。
This 功能团队实施时,它看起来可能是朝着正确方向迈出的一步,但即便如此,我们仍然需要一种方法来管理下游错误。
不幸的是,服务总线触发器(以及更普遍的 Azure Functions)目前不提供您需要的背压功能,因此您需要自己处理。
您描述的方法可行,您只需要在不同的函数应用程序中处理它,因为服务总线设置适用于整个应用程序,而不仅仅是一个函数。
在您的场景中可能没有太大帮助,但对于处理队列 2 或 3 的应用程序,您还可以尝试使用预览标志来限制应用程序的横向扩展实例的数量:WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT
.请注意,这是预览版,尚不能保证。
我鼓励您在记录您的场景的 functions repo 上打开一个问题。这类问题绝对是我们想要解决的问题,我们收到的反馈越多越好。
正是如此,除了正常的 api 端点之外,您能否要求您的下游人员提供队列端点?
然后你可以淹没他们的队列,他们可以在闲暇时处理它。
我目前正在评估使用服务总线和 azure 函数来触发一些需要通过下游 api 调用完成的工作。这一切都是非常标准的,除了我没有很好地处理下游系统过载时发生的事情 and/or 是 returning headers 以节流(即,每个 [=56 的最大调用数=]).我们似乎对队列触发器的强制节流没有任何动态控制。
我知道我们可以手动设置 max concurrency 但这并不一定能解决问题,因为我们无法控制下游系统并且需要考虑它可能会离线或变慢时间.
此外,我们可以创建消息,以便安排它们以特定速率流入,但下游系统仍然可以饱和或 return 速率限制。
选项 1:
假设消费计划,从解决方案的角度来看,这是我能想到的一种方式:
- Queue1 - 全速或最大速度。如果我们开始获得速率限制,请设置一个缓存值。如果设置了缓存值,则不处理该消息,将其克隆并放入queue2
- Queue2 - 低于最大 concurrency/prefetch 计数。与上述过程相同,但推入队列 3。
- Queue3 - 每个最大 concurrency/prefetch 计数最低。我们只是慢慢处理它们。
基本上,当下游系统饱和时,队列 1 成为队列 2 和队列 3 的控制器。
选项 2:
我们可以克隆消息并在将来重新排队,并继续这样做,直到它们都是进程。保留一个队列并重新排队直到我们处理它。
选项 3:
假设我们有自己的专用而不是消费的应用程序计划,我想我们可以 Thread.Sleep
如果函数接近速率限制或下降并继续重试。这可能是最大并发、实例和速率限制的计算。我不会在消费计划中考虑这一点,因为睡眠会大大增加成本。
我想知道我是否遗漏了处理下游饱和或限制队列触发器(可能是服务总线或存储队列)的最佳方式的简单方法
编辑: 我想补充一点,我将 100 万条消息发送到在发送时间安排的服务总线队列中。我观察到 Azure Function(消费计划)规模达到大约 1500/秒以提供一个很好的指标。我不确定专用的性能如何。
看来可以即时修改主机文件,设置立即生效。虽然这适用于所有功能,但它可能适用于我的特定情况(更新设置并根据速率限制每分钟左右再次检查一次)。
This 功能团队实施时,它看起来可能是朝着正确方向迈出的一步,但即便如此,我们仍然需要一种方法来管理下游错误。
不幸的是,服务总线触发器(以及更普遍的 Azure Functions)目前不提供您需要的背压功能,因此您需要自己处理。
您描述的方法可行,您只需要在不同的函数应用程序中处理它,因为服务总线设置适用于整个应用程序,而不仅仅是一个函数。
在您的场景中可能没有太大帮助,但对于处理队列 2 或 3 的应用程序,您还可以尝试使用预览标志来限制应用程序的横向扩展实例的数量:WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT
.请注意,这是预览版,尚不能保证。
我鼓励您在记录您的场景的 functions repo 上打开一个问题。这类问题绝对是我们想要解决的问题,我们收到的反馈越多越好。
正是如此,除了正常的 api 端点之外,您能否要求您的下游人员提供队列端点? 然后你可以淹没他们的队列,他们可以在闲暇时处理它。