Лучшая практика канала RabbitMQ
Я создаю API REST для отправки сообщения в RabbitMQ и пытался понять, как лучше всего создавать / закрывать каналы. Я использую RabbitMQ Java-клиент API.
В настоящее время у меня есть класс RabbitMQPublisherConnection
где я весной вставляю соединение RabbitMQ. Этот класс затем весной вводится в другой класс RabbitMQPublisherChannel
, Этот класс имеет следующую функцию для создания канала:
public class RabbitMQPublisherChannel { public Channel createChannel(String amqpExchange, String exchangeType, String queue, String routingKey, boolean durableExchange, boolean durableQueue, boolean autoDelete, com.rabbitmq.client.Connection connection) throws IOException { Channel channel = null; channel = connection.createChannel(); if ((amqpExchange != null) && !"".equals(amqpExchange.trim())) { if (log.isLoggable(Level.FINEST)) { log.finest("exchange:" + amqpExchange + ", type: " + exchangeType + ", durableExchange: " + durableExchange); } channel.exchangeDeclare(amqpExchange, exchangeType, durableExchange); channel.queueDeclare(queue, durableQueue, false, autoDelete, null); channel.queueBind(queue, amqpExchange, routingKey); } return channel; } }
Теперь у меня третий класс RabbitMQPublisher
где я весной впрыскиваю RabbitMQPublisherChannel
учебный класс. Мой контекст приложения выглядит так:
<bean id="rabbitMQPublisher" class="com.rabbitmq.RabbitMQPublisher">
<property name="publisherChannel" ref="rabbitMQPublisherChannel"/>
</bean>
<bean id="rabbitMQPublisherChannel" class="com.rabbitmq.RabbitMQPublisherChannel">
<property name="publisherConnection" ref="rabbitMQPublisherConnection"/>
</bean>
<bean id="rabbitMQPublisherConnection" class="com.rabbitmq.RabbitMQPublisherConnection">
<property name="rabbitMQConnectionSettingMap">
.. connection ..
</property>
</bean>
Класс RabbitMQPublisher
имеет функцию публикации сообщения в RabbitMQ:
public boolean publishMessage(String message, String queueName){
try {
// Validate queue name
com.rabbitmq.client.Channel channel = publisherChannel.getRabbitMQChannel(queueName);
RabbitMQConnection settings = publisherChannel.getPublisherConnection().getRabbitMQConnectionSettingMap().get(queueName);
if (channel != null) {
channel.basicPublish(settings.getAmqpExchange(), settings.getAmqpRoutingKey(), null, message.getBytes());
publisherChannel.closeChannel(channel);
}
} catch (AlreadyClosedException e) {
return FAILURE_RESPONSE;
} catch (IOException e) {
return FAILURE_RESPONSE;
}
return SUCCESS_RESPONSE;
}
Это приложение запускается через tomcat, и я заметил в AppDynamics, что закрытие канала занимает примерно 47% от общего времени, необходимого для публикации сообщения. Когда я удаляю вызов, чтобы закрыть канал, я экономлю эти 47% времени, которые равны 32 мс, но затем я замечаю в консоли управления RabbitMQ, что количество каналов для этого соединения постоянно увеличивается.
Так что мои вопросы -
- Является ли хорошей практикой открывать и закрывать канал после каждой публикации, предполагая, что tomcat будет получать несколько запросов в секунду?
- Является ли это хорошей практикой, чтобы пул каналов был разделен между несколькими потоками (что RabbitMQ рекомендует, но также говорит
Even so, applications should prefer using a Channel per thread instead of sharing the same Channel across multiple threads.
) Значит ли это создавать новый канал для каждого потока? - Будет ли хорошей практикой не закрывать канал, а через чистые каналы RabbitMQ http api очищать. (Пожалуйста, не рекомендуйте это)?
- Стоит ли экономить 32 мс?
Спасибо
1 ответ
Поскольку вы являетесь пользователем Spring Framework, рассмотрите возможность использования Spring AMQP. RabbitTemplate
использует кешированные каналы по одному соединению, причем канал извлекается из кеша (и возвращается) для каждой операции. Размер кэша по умолчанию равен 1, поэтому его обычно необходимо настроить для среды, подобной вашей.