У меня есть консольное приложение .NET Core, которое читает сообщение из RabbitMQ и сохраняет данные в базе данных. Он использует RabbitMQ.Client Assembly 5.1.0 и устанавливает EventingConsumer следующим образом:
var factory = new ConnectionFactory
{
HostName = _hostName,
UserName = _userName,
Password = _password,
RequestedHeartbeat = 20,
AutomaticRecoveryEnabled = true,
NetworkRecoveryInterval = TimeSpan.FromSeconds(10)
};
_connection = factory.CreateConnection();
_channel = _connection.CreateModel();
_channel.BasicQos(0, prefetchCount, false);
var consumer = new EventingBasicConsumer(_channel);
consumer.Received += HandleMessage;
_consumerTag = _channel.BasicConsume(_queueName, false, consumer);
Если я вызову _channel.BasicAck
для сообщения внутри моего метода HandleMessage
, то есть, как только получено каждое сообщение, скорость доставки сообщений составляет ~ 1500 в секунду. Однако я хочу дождаться подтверждения сообщения, пока оно не будет сохранено в БД. Если я это сделаю, скорость упадет до 300-500 в секунду.
Сохранение в БД осуществляется в отдельном потоке и не является узким местом. HandleMessage
только сохраняет сообщение в памяти для последующего сохранения в другом потоке. Я попытался поэкспериментировать с различными значениями prefetchCount
от 100 до 100 000, и это не имеет значения. Если я профилирую приложение, я вижу, что поток сеанса AMQP ("WorkPool-Session # 1: Connection (...)" тратит большую часть своего времени на ожидание WaitHandle в RabbitMQ.Client.ConsumerWorkService+WorkPool.Loop()
Что я делаю не так? Как я могу быстрее получать сообщения, не получая их сразу? (Сервер RabbitMQ 3.7.7)