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 管理控制台中注意到该连接的通道数量不断增加。

所以我的问题是 -

  1. 假设 tomcat 每秒会收到多个请求,这是在每次发布后打开和关闭频道的好习惯吗?
  2. 在多个线程之间共享通道池是否是一个好习惯(RabbitMQ recommends 但也表示 Even so, applications should prefer using a Channel per thread instead of sharing the same Channel across multiple threads.)这是否意味着为每个线程创建一个新通道?
  3. 不关闭通道并通过 RabbitMQ http api 清理空闲通道是否是一个好习惯。 (请不要推荐这个)?
  4. 节省 32 毫秒值得吗?

谢谢

由于您是 Spring 框架用户,请考虑使用 Spring AMQPRabbitTemplate 在单个连接上使用缓存通道,每个操作都从缓存中检出(并返回)该通道。默认缓存大小为1,所以一般需要为你这样的环境配置。