azure - 限制 Azure Functions 队列上的并发作业数量

标签 azure azure-functions azure-queues

我在 Azure 中有一个函数应用程序,当将项目放入队列时会触发该应用程序。它看起来像这样(大大简化):

public static async Task Run(string myQueueItem, TraceWriter log)
{
    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri(Config.APIUri);
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        StringContent httpContent = new StringContent(myQueueItem, Encoding.UTF8, "application/json");
        HttpResponseMessage response = await client.PostAsync("/api/devices/data", httpContent);
        response.EnsureSuccessStatusCode();

        string json = await response.Content.ReadAsStringAsync();
        ApiResponse apiResponse = JsonConvert.DeserializeObject<ApiResponse>(json);

        log.Info($"Activity data successfully sent to platform in {apiResponse.elapsed}ms.  Tracking number: {apiResponse.tracking}");
    }
}

这一切都很好并且运行得很好。每次将项目放入队列时,我们都会将数据发送到我们这边的某个 API 并记录响应。酷。

当“生成队列消息的事物”出现大幅增长并且同时将大量项目放入队列时,就会出现问题。这种情况往往在一分钟内发生大约 1,000 - 1,500 个项目。错误日志将包含以下内容:

2017-02-14T01:45:31.692 mscorlib: Exception while executing function: Functions.SendToLimeade. f-SendToLimeade__-1078179529: An error occurred while sending the request. System: Unable to connect to the remote server. System: Only one usage of each socket address (protocol/network address/port) is normally permitted 123.123.123.123:443.

起初,我认为这是 Azure Function 应用程序耗尽本地套接字的问题,如 illustrated here 。然而,后来我注意到了IP地址。 IP 地址 123.123.123.123(当然在本示例中有所更改)是我们的 IP 地址,即 HttpClient 发送到的 IP 地址。所以,现在我想知道是否是我们的服务器耗尽了套接字来处理这些请求。

无论哪种方式,我们都会遇到一个扩展问题。我正在尝试找出解决该问题的最佳方法。

一些想法:

  1. 如果是本地套接字限制,则 article above有一个使用 Req.ServicePoint.BindIPEndPointDelegate 增加本地端口范围的示例。这看起来很有希望,但是当您真正需要扩展时该怎么办?我不希望这个问题在 2 年后再次出现。
  2. 如果是远程限制,看起来我可以控制 Functions 运行时一次处理的消息数量。这里有一篇有趣的文章说您可以将 serviceBus.maxConcurrentCalls 设置为 1,并且一次只会处理一条消息。也许我可以将其设置为一个相对较低的数字。现在,在某个时刻,我们的队列填满的速度将快于我们处理它们的速度,但那时的答案是在我们的一端添加更多服务器。
  3. 多个 Azure Functions 应用程序?如果我有多个 Azure Functions 应用程序并且它们都在同一队列上触发,会发生什么情况? Azure 是否足够智能,可以在功能应用程序之间分配工作,并且我可以拥有一大群机器来处理我的队列,并且可以根据需要扩大或缩小队列?
  4. 我也遇到过保持事件的情况。在我看来,如果我能以某种方式在队列消息涌入时保持套接字打开,也许会有很大帮助。这可能吗?关于如何做到这一点有什么建议吗?

任何有关此类系统的推荐(可扩展!)设计的见解将不胜感激!

最佳答案

我认为代码错误是因为:using (var client = new HttpClient())

引自Improper instantiation antipattern :

this technique is not scalable. A new HttpClient object is created for each user request. Under heavy load, the web server may exhaust the number of available sockets.

关于azure - 限制 Azure Functions 队列上的并发作业数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42234413/

相关文章:

azure - 从azure函数发送HTTP响应

javascript - 无法从 CosmosDB 中删除项目

azure - 是否可以在 Windows Azure 中创建公共(public)队列?

azure - 了解耐用功能的实际好处

azure - 您可以从 Azure 队列触发器中弹出消息吗

java - 如何验证java中的azure上是否存在队列?

python - 通过 API 从 Azure DevOps 中提取团队成员

azure - Azure 中的 "Insufficient privileges to complete the operation."

java - 使用java通过microsoft graph访问office 365 planner

c# - Azure 服务总线主题超时异常