我正在创建一个 REST api 来向 RabbitMQ 发送消息,并试图了解创建/关闭 channel 的最佳实践是什么。我正在使用 RabbitMQ Java 客户端 API。
目前我有一个类RabbitMQPublisherConnection
,我在其中注入(inject) RabbitMQ 连接。然后这个类被 spring 注入(inject)到另一个类 RabbitMQPublisherChannel
中。该类具有以下创建 channel 的函数:
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
,我在其中注入(inject) 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 关闭 channel 所花费的时间约为发布消息总时间的 47%。当我删除关闭 channel 的调用时,我节省了 47% 的时间,相当于 32 毫秒,但随后我在 RabbitMQ 管理控制台中注意到该连接的 channel 数量不断增加。
所以我的问题是 -
- 假设 tomcat 每秒会收到多个请求,那么每次发布后打开和关闭 channel 是一个好习惯吗?
- 在多个线程之间共享 channel 池是一个好习惯吗(RabbitMQ recommends,但也说
即使如此,应用程序应该更喜欢每个线程使用一个 channel ,而不是在多个线程之间共享相同的 channel 。
) 这是否意味着为每个线程创建一个新 channel ? - 不关闭 channel 并通过 RabbitMQ http api 清理空闲 channel 是否是一个好习惯? (请不要推荐这个)?
- 是否值得节省 32 毫秒?
谢谢
最佳答案
由于您是 Spring Framework 用户,请考虑使用 Spring AMQP 。 RabbitTemplate
通过单个连接使用缓存 channel ,并为每个操作从缓存中 check out (并返回) channel 。默认缓存大小为1,因此一般需要针对您这样的环境进行配置。
关于java - RabbitMQ channel 最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29023156/