我正在使用Spring AMQP在不同服务之间设置远程处理,如here所述。但是,当我在配置上设置reply-timeout
时,第一个请求总是失败,因为声明队列,交换和绑定所花费的时间超过了超时:
RabbitAdmin组件可以声明交换,队列和绑定 在启动时。它通过ConnectionListener懒惰地这样做,所以如果 经纪人在启动时没有出现并不重要。第一次 听者将使用连接(例如通过发送消息) 将应用fire和管理员功能。
是否有任何方法可以在启动时急切地声明,而不是在第一个发布事件上进行,以防止第一个请求始终失败?
答案 0 :(得分:1)
如果您使用注释声明队列:
@Configuration
public class QueuesConfiguration {
@Bean
public FanoutExchange exchange() {
return new FanoutExchange("exchange", true, false);
}
@Bean
public Binding binding() {
return BindingBuilder.bind(queue()).to(exchange());
}
@Bean
public Queue queue() {
return new Queue("queue");
}
@Bean
public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
return new RabbitAdmin(connectionFactory);
}
}
然后在应用程序启动时手动调用RabbitAdmin.initialize()
:
@Component
public class ApplicationStartup implements ApplicationListener<ApplicationReadyEvent> {
@Autowired
private RabbitAdmin rabbitAdmin;
@Override
public void onApplicationEvent(final ApplicationReadyEvent event) {
rabbitAdmin.initialize();
}
}
答案 1 :(得分:0)
正如我们通过该说明和RabbitAdmin
中的代码看到的那样,最后一个只是将ConnectionListener
填充到提供的ConnectionFactory
。
从ConnectionListener.onCreate
调用ConnectionFactory.createConnection()
。
所以,你可以处理,例如,ContextRefreshedEvent
,并急切地做connectionFactory.createConnection()
。
来自另一方RabbitAdmin
具有initialize()
公共方法用于相同目的。
<强>更新强>
实际上ListenerContainer
也在其start()
上执行此操作。您必须在有听众的应用程序中声明您的队列,交换和绑定,并使其成为autoStartup = true
。说实话,监听器应用程序负责真正的Broker实体。
sending
应用只能与exchangeName
和routingKey
达成交易。