java - RabbitMQ channel 最佳实践

标签 java tomcat rabbitmq channel spring-rabbit

我正在创建一个 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 数量不断增加。

所以我的问题是 -

  1. 假设 tomcat 每秒会收到多个请求,那么每次发布后打开和关闭 channel 是一个好习惯吗?
  2. 在多个线程之间共享 channel 池是一个好习惯吗(RabbitMQ recommends,但也说即使如此,应用程序应该更喜欢每个线程使用一个 channel ,而不是在多个线程之间共享相同的 channel 。) 这是否意味着为每个线程创建一个新 channel ?
  3. 不关闭 channel 并通过 RabbitMQ http api 清理空闲 channel 是否是一个好习惯? (请不要推荐这个)?
  4. 是否值得节省 32 毫秒?

谢谢

最佳答案

由于您是 Spring Framework 用户,请考虑使用 Spring AMQPRabbitTemplate 通过单个连接使用缓存 channel ,并为每个操作从缓存中 check out (并返回) channel 。默认缓存大小为1,因此一般需要针对您这样的环境进行配置。

关于java - RabbitMQ channel 最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29023156/

相关文章:

java - cargo 嵌入式tomcat : custom context. xml

symfony - 对 Symfony Messenger 使用默认传输(跳过 amqp)

c# - RabbitMQ 公开的公钥中包含的证书链

java - 如何从 Android 中的 URL 获取参数?

java - Sakai 11 - 二进制安装成功且其 webapps 已部署,但它们无法启动

eclipse - 包含 Tomcat 7(当 servlet 项目时)未在 45 秒内启动...并且增加超时无法解决

javascript - 使用 Nestjs 监听多个 RabbitMQ 队列

java - 将 JavaMail 与自签名证书一起使用

java - 通过声明初始化类 DS 字段 - 在构造函数调用之前还是之后?

java - 如何从 .NET 应用程序访问 HSQL 数据库?