我正在创建一个 REST api 来向 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 清理通道是否是一个好习惯。(请不要推荐这个)?
- 节省 32ms 值得吗?
谢谢