如何在Spring AMQP中侦听现有队列?

时间:2018-08-30 12:02:19

标签: java spring rabbitmq amqp spring-amqp

我有一台远程RabbitMQ服务器,其中有一些我想听的队列。我尝试过:

@RabbitListener(queues = "queueName")
public void receive(String message) {
    System.out.println(message);
}

但是它试图创建一个新的队列。结果是可预测的-访问被拒绝。

o.s.a.r.listener.BlockingQueueConsumer   : Failed to declare queue: queueName

我没有以其他任何方式声明任何队列。

如何收听远程服务器上的现有队列?另外,有没有办法检查此队列是否存在?我看到了这条线

@RabbitListener(queues = "#{autoDeleteQueue2.name}")

在教程中。 #{queueName.name}是什么意思?

日志和堆栈跟踪的开头:

2018-08-30 22:10:21.968  WARN 12124 --- [cTaskExecutor-1] o.s.a.r.listener.BlockingQueueConsumer   : Failed to declare queue: queueName
2018-08-30 22:10:21.991  WARN 12124 --- [cTaskExecutor-1] o.s.a.r.listener.BlockingQueueConsumer   : Queue declaration failed; retries left=3

org.springframework.amqp.rabbit.listener.BlockingQueueConsumer$DeclarationException: Failed to declare queue(s):[queueName]
    at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.attemptPassiveDeclarations(BlockingQueueConsumer.java:711) ~[spring-rabbit-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:588) ~[spring-rabbit-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:996) [spring-rabbit-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131]

3 个答案:

答案 0 :(得分:2)

即使您没有对代理的配置权限,侦听器使用的queueDeclarePassive也是允许的(它检查队列的存在)。

  

o.s.a.r.listener.BlockingQueueConsumer:无法声明队列:queueName

那只是意味着队列不存在。

  

@RabbitListener(queues = "#{autoDeleteQueue2.name}")

用于在运行时(当您有权创建队列时)获取队列名称。

例如

@Bean
public AnonymousQueue autoDeleteQueue2() {
    return new AnonymousQueue();
}

Spring将使用一个随机的唯一名称将该队列添加到代理中。然后,使用实际的队列名称配置侦听器。

答案 1 :(得分:1)

以下是有关如何使用RabbitMq监听队列的示例:

@Component
public class RabbitConsumer implements MessageListener {

    @RabbitListener(bindings =
    @QueueBinding(
            value = @Queue(value = "${queue.topic}", durable = "true"),
            exchange = @Exchange(value = "${queue.exchange}", type = ExchangeTypes.FANOUT, durable = "true")
    )
    )
    @Override
    public void onMessage(Message message) {
        // ...
    }
}

和配置(application.yaml):

queue:
  topic: mytopic
  exchange: myexchange

在Rabbitmq中,消费者与交易所相关联。它允许您定义必须如何使用消息(所有消费者都听所有消息吗?如果只有一个消费者阅读该消息就足够了吗?...

答案 2 :(得分:0)

这里是一个如何使用Spring Integration监听特定“队列”的示例:

SpringIntegrationConfiguration.java

@Configuration
public class SpringIntegrationConfiguration {

@Value("${rabbitmq.queueName}")
private String queueName;

@Bean
public IntegrationFlow ampqInbound(ConnectionFactory connectionFactory) {
    return IntegrationFlows.from(Amqp.inboundAdapter(connectionFactory, queueName))
            .handle(System.out::println)
            .get();
  }
}

ApplicationConfiguration.java

@Configuration
public class ApplicationConfiguration {

@Value("${rabbitmq.topicExchangeName}")
private String topicExchangeName;

@Value("${rabbitmq.queueName}")
private String queueName;

@Value("${rabbitmq.routingKey}")
private String routingKey;

@Bean
Queue queue() {
    return new Queue(queueName, false);
}

@Bean
TopicExchange exchange() {
    return new TopicExchange(topicExchangeName);
}

@Bean
Binding binding(Queue queue, TopicExchange exchange) {
    return BindingBuilder.bind(queue).to(exchange).with(routingKey);
  }

}

Application.yml

rabbitmq:
topicExchangeName: spring-boot-exchange
queueName: spring-boot
routingKey: foo.bar.#