如何处理对 Azure 服务总线的多次访问

How to handle multiples accesses to azure service bus

我的应用程序正在使用 Azure 服务总线来存储消息。我有一个名为 HttpTriggerEnqueue 的 Azure 函数,它允许我对消息进行排队。问题是这个函数可以在很短的时间间隔内被调用数百次。当我调用 HttpTriggerEnqueue 一次、两次、10 次或 50 次时,一切正常。但是当我调用它 200 次、300 次(这是我的用例)时,我得到一个错误,并不是所有的消息都被排队。从功能门户我得到以下错误。

threshold exceeded [connections]

我尝试了 .NET sdk 和 HTTP 请求。这是我的代码

HTTP 请求:

try
{
    var ENQUEUE = "https://<MyNamespace>.servicebus.windows.net/<MyEntityPath>/messages";
    var client = new HttpClient(new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip });
    var request = new HttpRequestMessage(HttpMethod.Post, ENQUEUE);
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    var sasToken = SASTokenGenerator.GetSASToken(
                    "https://<MyNamespace>.servicebus.windows.net/<MyEntityPath>/",
                    "<MyKeyName>",
                    "<MyPrimaryKey>",
                    TimeSpan.FromDays(1)
                );


    client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", sasToken);

    request.Content = new StringContent(message, Encoding.UTF8, "application/json");
    request.Headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
    request.Headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));

    var res = await client.SendAsync(request);
}
catch (Exception e) { }

以及使用SDK的代码:

var qClient = QueueClient.CreateFromConnectionString(MyConnectionString, MyQueueName);
var bMessage = new BrokeredMessage(message);
qClient.Send(bMessage);
qClient.Close();

我在 Azure 上有标准层定价。 如果我在一小段时间间隔内调用该函数 300 次(例如),我就会收到错误消息。我该如何解决?

您应该使用 Service Bus output binding 从 Azure 函数向服务总线发送消息。它将为您处理连接管理,因此您不应该遇到此类错误。

这里的实际问题不在于服务总线绑定(尽管您应该遵循@Mikhail 给出的建议),这是 HttpClient 的一个众所周知的问题。您不应该在每次调用函数时都重新创建 HttpClient。将其存储在静态字段中,以便可以重复使用。 Read this blog post for a great breakdown on the actual issue。要点是,除非您将其重构为使用 HttpClient 的单个实例,否则您将继续 运行 端口耗尽。

来自MSDN Docs

HttpClient is intended to be instantiated once and re-used throughout the life of an application. Especially in server applications, creating a new HttpClient instance for every request will exhaust the number of sockets available under heavy loads. This will result in SocketException errors.