将多个@RabbitListener Bean添加到ContainerFactory

时间:2019-01-28 19:45:41

标签: java spring-mvc rabbitmq spring-amqp spring-rabbitmq

这是我的@Configuration

   @Bean
    public AmqpAdmin amqpAdmin()
    {
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory());

        DirectExchange dirExchange = new DirectExchange("evtExchange", true,
                false);

        rabbitAdmin.declareExchange(dirExchange);
        rabbitAdmin.declareQueue(processQueue);
        Binding processBinding = BindingBuilder.bind(processQueue)
                .to(dirExchange).with("rkey.process");
        rabbitAdmin.declareBinding(processBinding);

        return rabbitAdmin;
    }

    @Bean
    public RabbitTemplate rabbitTemplate()
    {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory());
        return rabbitTemplate;
    }

    @Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory()
    {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory());
        SimpleMessageListenerContainer container = factory
                .createListenerContainer();
        factory.setConcurrentConsumers(50);
        factory.setMaxConcurrentConsumers(100);
        container.setStartConsumerMinInterval(3000);
        container.setQueues(processQueue);
        factory.setAdviceChain(retryInterceptor());
        return factory;
    }

    @Bean
    public RetryOperationsInterceptor retryInterceptor()
    {
        return RetryInterceptorBuilder.stateless().maxAttempts(5)
                .backOffOptions(1000, 2.0, 10000).recoverer(new RejectAndDontRequeueRecoverer()).build();
    }

    @Bean
    public ProcessQueueListener processListener()
    {
        return new ProcessQueueListener();
    }

    @Bean
    public ProcessQueueListener processListener2()
    {
        return new ProcessQueueListener();
    }

    @Bean
    public ProcessQueueListener processListener3()
    {
        return new ProcessQueueListener();
    }

这是@RabbitListener

@RabbitListener(containerFactory = "rabbitListenerContainerFactory", queues = "process")
public class ProcessQueueListener
{

    public ProcessQueueListener()
    {
    }

    @RabbitHandler
    void receiveMessage(String message)
    {
        // doSomething
    }

} 

仅当分别实例化processListener()processListener2()processListener3()时,我才开始在RabbitMQ Admin中看到进程队列的多个使用者,并且每个侦听器都处理消息,否则,尽管指定了setConcurrentConsumers()

,但只看到一个消费者

是否存在一种优雅的方法来按需声明多个侦听器,并根据需要进行增加和减少。还是声明多个@Bean是唯一的选择?还是我做错了什么?

1 个答案:

答案 0 :(得分:1)

您使用的是什么版本?

我刚刚复制了您的容器工厂,对我来说很好(2.1.3)...

enter image description here

顺便说一句,从2.0版开始,您可以将concurrency添加到@RabbitListener,它将覆盖容器工厂中的任何值。

/**
 * Set the concurrency of the listener container for this listener. Overrides the
 * default set by the listener container factory. Maps to the concurrency setting of
 * the container type.
 * <p>For a
 * {@link org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer
 * SimpleMessageListenerContainer} if this value is a simple integer, it sets a fixed
 * number of consumers in the {@code concurrentConsumers} property. If it is a string
 * with the form {@code "m-n"}, the {@code concurrentConsumers} is set to {@code m}
 * and the {@code maxConcurrentConsumers} is set to {@code n}.
 * <p>For a
 * {@link org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer
 * DirectMessageListenerContainer} it sets the {@code consumersPerQueue} property.
 * @return the concurrency.
 * @since 2.0
 */
String concurrency() default "";

也是无关的,但是您不应该在bean声明中执行此rabbitAdmin.declareExchange(dirExchange) -在应用程序上下文生命周期中,连接到RabbitMQ还为时过早。将交换,队列和绑定添加为@Bean,管理员将自动查找并声明它们。