Azure Functions -并行/并发功能执行和横向扩展

rjee0c15  于 2023-01-02  发布在  其他
关注(0)|答案(3)|浏览(172)

我最近开始使用Azure Functions,(在阅读了SO和Microsoft文档之后)在理解横向扩展和并行执行方面遇到了困难。
我的情况是一个带有CRUD Azure Functions的函数应用-它们需要像REST API一样快速并发地做出React。然而,当在我自己的浏览器上测试并运行10个不同的标签时,似乎标签是连续/顺序完成的(一个接一个,最后一个标签等待了很长时间)。
我想知道我是否遗漏了什么,或者是否有一种方法允许使用其他Azure产品并行执行?
(我已经了解了一些应用程序设置,可能使用APIM或托管函数,但这些似乎不是答案。)
谢谢!

z18hc3ub

z18hc3ub1#

我认为你有几个不同的问题需要解决:
第一个是你的浏览器可能有一个并发连接限制到一个单一的域。大多数现代浏览器将限制到6。这个限制不是在每个标签的基础上,但适用于浏览器中所有打开的标签。所以在你的情况下,你有10个打开的标签,最好的情况是,其中4个将等待其他6个完成。您可能想要查看类似Fiddler的东西,或者特定于负载测试的工具来绕过这个限制。
您可能遇到的下一个问题是无服务器冷启动。这是指一段时间内未执行的无服务器代码“卸载”。然后,当稍后调用时,会有一个相关的启动时间来准备函数的执行。

同一篇文章给出了一些缓解这个问题的想法。一个是在应用服务中运行Azure功能,你可以设置为总是运行。然而,这意味着你的Azure功能不再是无服务器的。
另一种选择是使用Azure功能的高级计划中提供的预热示例。
最后,您可能需要扩展计划可以横向扩展到的示例数。如果您的计划仅设置为横向扩展到1个示例,则您的每一个调用都将等待前一个调用完成。如果您将这些调用横向扩展到10个,则它们都可以并发运行。

9wbgstp7

9wbgstp72#

我想冷启动的问题已经提到了。
除了支付更多的费用(应用服务计划或高级计划),另一个选择是多写一点代码来保存一大笔钱。

  • 添加一个新的查询参数?keepWarm=1到你想要保持温暖的REST API端点。如果是keepWarm调用,这个函数的实现将返回200。
  • 添加一个计划函数(定时器触发器),该函数每X秒唤醒一次,调用/endpoint?keepWarm=1

在消费计划中主持这一切。
即使是X = 1 second,你最终可能会比其他昂贵的计划(100美元以上,我想)少花很多钱(5 -20美元)。
IMHO高级和专用计划是当你需要更多的火力,而不是当你想保持温暖。事实上,消费计划将允许你扩展到200个示例,而其他昂贵的计划的限制是10到100个。
有了昂贵的计划,你确实可以得到更多的火力,这样你就可以做更大的任务,并采取只要你喜欢:

  • 210-840加速老化单元
  • 1.75- 14 GB内存
  • 无限执行时间限制(#)

($)无界执行时限:如果您的触发器是HTTP触发器(REST API),则由于负载平衡器的限制,这是无用的
如果使用HTTP触发器的函数未在230秒内完成,Azure负载平衡器将超时并返回HTTP 502错误。该函数将继续运行,但将无法返回HTTP响应。

缩放单位:

这是非常不清楚的。

缩放功能应用程序示例

作为described here

  • 在消费和高级计划中,Azure Functions通过添加Functions主机的其他示例来扩展CPU和内存资源。示例数取决于触发函数的事件数。*
  • 消耗计划中的每个函数主机示例限制为1.5 GB内存和一个CPU。主机示例是整个函数应用程序,这意味着函数应用程序中的所有函数共享示例中的资源并同时缩放。*
  • 很明显的是
  • 当AFR(Azure函数运行时)发现需要扩展(基于流量)时,它将生成新的函数主机,每个主机包含整个函数应用程序及其所有函数。
  • 作为一个开发人员,你必须以这样的方式创建你的函数,即它们将它们的资源使用限制在一个函数主机所提供的资源上。
  • 不清楚的是
  • 每个主机是否仅具有每个功能的一个示例或多个示例。
  • 是否并行执行同一应用程序中的多个不同函数。如果是,则每个函数实现需要与此应用程序中共存的其他函数共享主机资源。

缩放辅助进程

也可以通过应用程序设置设置FUNCTIONS_WORKER_PROCESS_COUNT来控制language worker processes的数量。
我猜在这种情况下,每个语言工作进程将在同一主机上运行,并共享资源。

wmtdaxz3

wmtdaxz33#

我不确定你的所有用例,但我想我会提到,如果有任何用例不需要同步,你可以创建一个HTTP触发器函数,它所做的一切就是把请求放入一个队列,然后你可以使用队列触发器函数来处理它。
但是,要注意队列触发器的向外扩展,我有一个队列触发器,它向外扩展并占用了所有的DB连接,因为这是ETL作业的一部分,所以我将队列函数归为

[Singleton(Mode = SingletonMode.Listener)]

此外,对于队列,您需要设置队列深度和有害消息的警报。
Qupla!(金隆祝你好运)!

相关问题