У нас есть веб-приложение Azure для получения, обработки и завершения сообщений в очередях. Это работает, но мы находим компромиссы, которые снижают производительность или вызывают исключения в базовом пакете SDK служебной шины. Нам необходимо обрабатывать примерно 400 тысяч сообщений в день.
Я воспроизвел наши проблемы в фрагменте кода ниже.
- В настоящее время при использовании приведенного ниже кода обработка сообщений из
очереди происходит медленно, пока она ожидает завершения последнего сообщения, прежде чем
перейти к следующему сообщению. Мы не обрабатываем сообщения достаточно быстро, чтобы успевать за пиковым количеством сообщений. Используя этот код, мы обрабатываем примерно 1000 сообщений за 5 минут. - Если мы заменим получателя.CompleteMessageAsync(message).Wait();< /code>
с получателем.CompleteMessageAsync(message);
В отношении обработанного нами сообщения возникло исключение. Сообщения обрабатываются (в нашем приложении) и помещаются в очередь, но Application Insights показывает сотни тысяч исключений. Предположительно потому, что мы утилизируем приемник до того, как он будет полностью завершен.
, ни при доступе к ее свойству Exception. В результате ненаблюдаемое
исключение было повторно создано потоком финализатора. Предоставленный замок
недействителен. Либо срок действия блокировки истек, либо сообщение уже
удалено из очереди, либо было получено другим экземпляром
получателя.
< ol start="3">
[*]Если мы не избавимся от получателя и клиента, количество подключений и памяти веб-приложения увеличится. Ничего не будет выпущено, и веб-приложение упадет.
Как правильно распорядиться клиентом и получателем, завершить сообщение, не вызывая исключений и достичь желаемой производительности?
internal void Listen()
{
var client = new ServiceBusClient(_host);
ServiceBusReceiver receiver = client.CreateReceiver(queue, new ServiceBusReceiverOptions
{
SubQueue = SubQueue.None,
ReceiveMode = ServiceBusReceiveMode.PeekLock
});
IReadOnlyList messages = receiver.ReceiveMessagesAsync(fetchCount, wait).Result;
foreach (var message in messages)
{
try
{
Console.WriteLine(message.Body + " " + message.LockedUntil);
//This causes exceptions when the receiver is disposed
// receiver.CompleteMessageAsync(message);
//this is slower to process
receiver.CompleteMessageAsync(message).Wait();
}
catch (Exception ex)
{
Console.WriteLine(ex);
Console.ReadLine();
throw;
}
}
//if we don't dispose, the connections and memory use in the web app will increase to breaking point.
receiver.DisposeAsync();
client.DisposeAsync();
Console.ReadLine();
}
}
Подробнее здесь: https://stackoverflow.com/questions/792 ... ow-c-sharp
Мобильная версия