如何处理对 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.
我的应用程序正在使用 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.