如何让Spring RabbitMQ创建一个新的Queue?

在使用rabbit-mq的(有限)经验中,如果为尚不存在的队列创建新的侦听器,则会自动创建队列。 我正在尝试使用带有rabbit-mq的Spring AMQP项目来设置一个监听器,而我正在收到错误。 这是我的xml配置:

      

我在RabbitMq日志中得到了这个:

 =ERROR REPORT==== 3-May-2013::23:17:24 === connection , channel 1 - soft error: {amqp_error,not_found,"no queue 'test' in vhost '/'",'queue.declare'} 

和AMQP的类似错误:

 2013-05-03 23:17:24,059 ERROR [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-1) - Consumer received fatal exception on startup org.springframework.amqp.rabbit.listener.FatalListenerStartupException: Cannot prepare queue for listener. Either the queue doesn't exist or the broker will not allow us to use it. 

从堆栈跟踪看来,队列是以“被动”模式创建的 – 任何人都可以指出我是如何创建不使用被动模式的队列所以我没有看到这个错误? 还是我错过了别的什么?

较旧的post,但这仍然在谷歌上显得相当高,所以这里有一些新的信息:

2015年11月23日

Spring 4.2.x开始使用Spring-Messaging和Spring-Amqp 1.4.5.RELEASESpring-Rabbit 1.4.5.RELEASE ,通过@Configuration类声明交换,队列和绑定变得非常简单了一些注释:

 @EnableRabbit @Configuration @PropertySources({ @PropertySource("classpath:rabbitMq.properties") }) public class RabbitMqConfig { private static final Logger logger = LoggerFactory.getLogger(RabbitMqConfig.class); @Value("${rabbitmq.host}") private String host; @Value("${rabbitmq.port:5672}") private int port; @Value("${rabbitmq.username}") private String username; @Value("${rabbitmq.password}") private String password; @Bean public ConnectionFactory connectionFactory() { CachingConnectionFactory connectionFactory = new CachingConnectionFactory(host, port); connectionFactory.setUsername(username); connectionFactory.setPassword(password); logger.info("Creating connection factory with: " + username + "@" + host + ":" + port); return connectionFactory; } /** * Required for executing adminstration functions against an AMQP Broker */ @Bean public AmqpAdmin amqpAdmin() { return new RabbitAdmin(connectionFactory()); } /** * This queue will be declared. This means it will be created if it does not exist. Once declared, you can do something * like the following: * * @RabbitListener(queues = "#{@myDurableQueue}") * @Transactional * public void handleMyDurableQueueMessage(CustomDurableDto myMessage) { * // Anything you want! This can also return a non-void which will queue it back in to the queue attached to @RabbitListener * } */ @Bean public Queue myDurableQueue() { // This queue has the following properties: // name: my_durable // durable: true // exclusive: false // auto_delete: false return new Queue("my_durable", true, false, false); } /** * The following is a complete declaration of an exchange, a queue and a exchange-queue binding */ @Bean public TopicExchange emailExchange() { return new TopicExchange("email", true, false); } @Bean public Queue inboundEmailQueue() { return new Queue("email_inbound", true, false, false); } @Bean public Binding inboundEmailExchangeBinding() { // Important part is the routing key -- this is just an example return BindingBuilder.bind(inboundEmailQueue()).to(emailExchange()).with("from.*"); } } 

一些来源和文档可以提供帮助:

  1. spring注释
  2. 声明/配置RabbitMQ以获得队列/绑定支持
  3. 直接交换绑定(当路由密钥无关紧要时)

注意 :看起来我错过了一个版本 – 从Spring AMQP 1.5开始 ,事情变得更加容易,因为你可以在听众声明完整的绑定!

似乎解决我的问题的是添加管理员。 这是我的xml:

        

您可以在连接标记之后但在侦听器之前添加此项:

  

不幸的是,根据XSD架构,被动属性(上面列出的)无效。 但是,在我看到的每个queue_declare实现中,passive都是一个有效的queue_declare参数。 我很想知道这是否有效,或者他们是否打算将来支持它。

以下是队列声明的完整选项列表: http : //www.rabbitmq.com/amqp-0-9-1-reference.html#class.queue

这里是春兔模式的完整XSD(包括评论): http : //www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd