我想为使用rabbitMq的服务运行一些验收测试,但我想忽略所有需要服务间通信(amqp)的服务。
然而问题是Spring尝试在启动时连接到(非现有的)Rabbit主机,以便它可以注册其消费者。它为每个使用@RabbitListener
注释的方法执行此操作,如果我的服务中有多个侦听器,则会因长时间超时而烦恼。
如何减少此超时甚至阻止@RabbitListener连接?
我们的(简化)兔子配置:
@Configuration
@EnableRabbit
public class RabbitMqConfig {
public RabbitMqConfig(
@Value("${rabbitmq.host}") String rabbitHost,
@Value("${rabbitmq.port}") int rabbitPort,
@Value("${exchange.name}") String exchange) {
this.rabbitHost = rabbitHost;
this.rabbitPort = rabbitPort;
this.exchange= exchange;
}
@Bean
DirectExchange directExchangeBean() {
return new DirectExchange(this.exchange, true, false);
}
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(rabbitHost);
connectionFactory.setPort(rabbitPort);
return connectionFactory;
}
@Bean
public RabbitTemplate rabbitTemplate() {
return new RabbitTemplate(connectionFactory());
}
@Bean
public Queue itemDoneQueue() {
return new Queue(ITEM_DONE_QUEUENAME, true);
}
@Bean
Binding itemDoneBinding() {
return BindingBuilder.bind(itemDoneQueue()).to(directExchangeBean()).with(ITEM_DONE_KEY);
}
}
属性
rabbitmq.host=192.168.42.100
rabbitmq.port=5672
exchange.name=myExchange
听众:
@RabbitListener(queues = ITEM_DONE_QUEUENAME)
public void receiveMessageFromItemDoneQueue(String message) {
// do the work
}
测试:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Application.class})
public abstract class RabbitTest {
这里真的没什么特别的。显然,在测试期间,兔主机不可用。那样就好。我想忽略这个事实。很快。
我试过
spring.rabbitmq.connection-timeout=1
但这并没有改变任何事情。
使用
spring.rabbitmq.listener.simple.auto-startup=false
两者都没有。
使用
spring.autoconfigure.exclude:org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration
只是通过抱怨NoSuchBeanDefinitionException: No bean named 'rabbitListenerContainerFactory' available
有什么想法吗? 谢谢!
答案 0 :(得分:2)
我遇到了类似的问题,但是用
解决了 spring.rabbitmq.listener.direct.auto-startup=false
SpringBoot版本2.2.4.RELEASE
Spring框架版本5.2.3.RELEASE
答案 1 :(得分:1)
我希望children
可以正常工作 - 你确定你没有尝试用其他代码连接到Rabbit吗?当设置为false时,您能提供DEBUG日志来显示问题吗?
您可以使用the JUnit BrokerRunning
@Rule跳过任何需要真正RabbitMQ代理的测试。
答案 2 :(得分:1)
如果属性spring.rabbitmq.listener.simple.auto-startup=false
无效,则您可能正在定义自己的SimpleRabbitListenerContainerFactory
bean
检查如何在RabbitAnnotationDrivenConfiguration.rabbitListenerContainerFactory()
SimpleRabbitListenerContainerFactoryConfigurer
将SimpleRabbitListenerContainerFactory
和application.properties
中定义的属性绑定在一起(除其他外)
如果使用自己的定义,请确保使用类似
的内容@Bean
SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(
SimpleRabbitListenerContainerFactoryConfigurer containerFactoryConfigurer,
ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory listenerContainerFactory =
new SimpleRabbitListenerContainerFactory();
containerFactoryConfigurer.configure(listenerContainerFactory, connectionFactory);
return listenerContainerFactory;
}
答案 3 :(得分:0)
感谢您的投入加里。
我已经找到了适合我的解决方案。由于某种原因,消费者初始化的连接超时未在我使用的CachingConnectionFactory
中公开,也不是我尝试使用的属性(spring.rabbitmq.connection-timeout
)。
我现在所做的是初始化基本ConnectionFactory并将其传递给CachingConnectionFactory(当然不知道差异在哪里,但大多数情况下都是春天的情况):
@Bean
public ConnectionFactory connectionFactory() {
com.rabbitmq.client.ConnectionFactory connectionFactory = new com.rabbitmq.client.ConnectionFactory();
connectionFactory.setConnectionTimeout(this.connectionTimeout);
connectionFactory.setHost(this.rabbitHost);
connectionFactory.setPort(this.rabbitPort);
CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory(
connectionFactory);
return cachingConnectionFactory;
}
现在,我可以在接受测试期间将超时设置为1,从而导致消费者初始化快速失败并达到更高的部署值。
答案 4 :(得分:0)
您可以使用mockito模拟连接工厂,并添加BrokerRunning.isNotRunning()
@Bean
ConnectionFactory connectionFactory() {
ConnectionFactory factory = mock(ConnectionFactory.class);
Connection connection = mock(Connection.class);
Channel channel = mock(Channel.class);
willReturn(connection).given(factory).createConnection();
willReturn(channel).given(connection).createChannel(anyBoolean());
given(channel.isOpen()).willReturn(true);
return factory;
}
这是您将添加到测试中的规则:
@Rule
public BrokerRunning brokerRunning = BrokerRunning.isNotRunning();