RabbitMQ 通道最佳实践
RabbitMQ channel best practice
我正在创建一个 REST api 来向 RabbitMQ 发送消息,并试图了解什么是 creating/closing 通道的最佳实践。我正在使用 RabbitMQ Java 客户端 api。
目前我有一个 class RabbitMQPublisherConnection
我 spring 注入 RabbitMQ 连接。这个 class 然后 spring 注入另一个 class RabbitMQPublisherChannel
。此 class 具有以下创建频道的功能:
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;
} }
现在我有第三个 class RabbitMQPublisher
,我 spring 注入 RabbitMQPublisherChannel
class。我的应用程序上下文如下所示:
<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>
classRabbitMQPublisher
有发布消息到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 recommends 但也表示
Even so, applications should prefer using a Channel per thread instead of sharing the same Channel across multiple threads.
)这是否意味着为每个线程创建一个新通道?
- 不关闭通道并通过 RabbitMQ http api 清理空闲通道是否是一个好习惯。 (请不要推荐这个)?
- 节省 32 毫秒值得吗?
谢谢
由于您是 Spring 框架用户,请考虑使用 Spring AMQP。 RabbitTemplate
在单个连接上使用缓存通道,每个操作都从缓存中检出(并返回)该通道。默认缓存大小为1,所以一般需要为你这样的环境配置。
我正在创建一个 REST api 来向 RabbitMQ 发送消息,并试图了解什么是 creating/closing 通道的最佳实践。我正在使用 RabbitMQ Java 客户端 api。
目前我有一个 class RabbitMQPublisherConnection
我 spring 注入 RabbitMQ 连接。这个 class 然后 spring 注入另一个 class RabbitMQPublisherChannel
。此 class 具有以下创建频道的功能:
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; } }
现在我有第三个 class RabbitMQPublisher
,我 spring 注入 RabbitMQPublisherChannel
class。我的应用程序上下文如下所示:
<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>
classRabbitMQPublisher
有发布消息到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 recommends 但也表示
Even so, applications should prefer using a Channel per thread instead of sharing the same Channel across multiple threads.
)这是否意味着为每个线程创建一个新通道? - 不关闭通道并通过 RabbitMQ http api 清理空闲通道是否是一个好习惯。 (请不要推荐这个)?
- 节省 32 毫秒值得吗?
谢谢
由于您是 Spring 框架用户,请考虑使用 Spring AMQP。 RabbitTemplate
在单个连接上使用缓存通道,每个操作都从缓存中检出(并返回)该通道。默认缓存大小为1,所以一般需要为你这样的环境配置。