我正在使用带有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]
如何解决这个问题?
答案 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