2

我正在创建一个 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 管理控制台中注意到该连接的通道数量一直在增加。

所以我的问题是——

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

谢谢

4

1 回答 1

3

由于您是 Spring Framework 用户,请考虑使用Spring AMQP。在RabbitTemplate单个连接上使用缓存通道,每个操作的通道都从缓存中检出(并返回)。默认缓存大小为 1,因此一般需要针对像您这样的环境进行配置。

于 2015-03-13T13:37:34.033 回答