与rabbitmq SimpleMessageListenerContainer集成时,Spring-boot启动速度很慢

时间:2018-03-17 07:52:22

标签: spring-boot rabbitmq

我正在使用带有spring-boot的rabbitmq,这是我的消费者配置:

@Bean(value = "distributionMqConnectionFactory")
public ConnectionFactory distributionMqConnectionFactory(){
    CachingConnectionFactory connectionFactory=new CachingConnectionFactory();
    connectionFactory.setAddresses(distributionMqServerAddress);
    connectionFactory.setVirtualHost(distributionMqServerVirtualHost);
    connectionFactory.setUsername(distributionMqServerUserName);
    connectionFactory.setPassword(distributionMqServerPassword);
    return connectionFactory;
}

@Bean(value = "distributionMessageListenerContainer")
public SimpleMessageListenerContainer distributionMessageListenerContainer(@Qualifier("distributionMqConnectionFactory") ConnectionFactory connectionFactory,
                                                                           @Qualifier("distributionMqConsumer") DistributionMqConsumer mqConsumer, @Qualifier("distributionConsumerQueue") Queue queue) {
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
    container.setConnectionFactory(connectionFactory);
    container.setQueues(queue);
    container.setRabbitAdmin(distributionRabbitAdmin());
    container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
    container.setAutoStartup(false);
    if (distributionMqConsumerEnable) {
        container.setMessageListener(mqConsumer);
        container.start();
    }
    return container;
}

如果我设置distributionMqConsumerEnable=true并启动应用程序,它启动速度非常慢,但是当设置为distributionMqConsumerEnable=false时,它变得正常,在查看控制台输出后,我发现它阻塞了

[INFO] [org.springframework.amqp.rabbit.connection.CachingConnectionFactory:359] Created new connection: SimpleConnection@21561d6 [delegate=amqp://guest@127.0.0.1:5672/, localPort= 51131]

如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

我发现container.start();中存在问题,我们可以在源代码中看到:

/**
 * Retrieve the fatal startup exception if this processor completely failed to locate the broker resources it
 * needed. Blocks up to 60 seconds waiting for an exception to occur
 * (but should always return promptly in normal circumstances).
 * No longer fatal if the processor does not start up in 60 seconds.
 * @return a startup exception if there was one
 * @throws TimeoutException if the consumer hasn't started
 * @throws InterruptedException if the consumer startup is interrupted
 */
private FatalListenerStartupException getStartupException() throws TimeoutException, InterruptedException {
    this.start.await(60000L, TimeUnit.MILLISECONDS); //NOSONAR - ignore return value
    return this.startupException;
}

所以我认为mq bean初始化了,并且在读完后等待其他东西: http://forum.spring.io/forum/spring-projects/integration/amqp/747305-60-seconds-delay-when-calling-start-on-simplemessagelistenercontainer,我决定在我的应用程序中的所有spring bean准备就绪后做container.start(),并且它可以工作。这是我的解决方案:

@Component
public class TeddySmartLifeCycleConfig implements SmartLifecycle{
    @Autowired
    @Qualifier("distributionMessageListenerContainer")
    private SimpleMessageListenerContainer distributionContainer;
    //start mq containter
    private void startMqConsumer(){
        distributionContainer.start();
    }
    @Override
    public boolean isAutoStartup() {
        return true; //return true so start() method will be called
    }

    @Override
    public void stop(Runnable callback) {

    }
    //this will called when all beans are ready
    @Override
    public void start() {
        startMqConsumer();
    }

您可以谷歌了解SmartLifecycle

的更多信息