具有空队列名称的Spring AMQP入站适配器

时间:2018-05-25 12:49:32

标签: rabbitmq spring-integration spring-amqp

我正在使用Spring AMQP开发一个消费者应用程序,它接收来自RabbitMQ的消息。宣布了一个主题交换。要连接到Rabbit,我创建一个空名称的队列,因为代理将提供自动队列名称,请参阅the specs

@Bean
public TopicExchange exchange() {
    TopicExchange topicExchange = new TopicExchange(topicExchangeName);
    topicExchange.setShouldDeclare(false);
    return topicExchange;
}

@Bean
public Queue queue() {
  return new Queue("", queueDurable, queueExclusive, queueAutoDelete, queueParameters);
}

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

但是当我尝试使用Spring Integration Java DSL配置AMQP Inbound Channel Adapter时:

@Autowired
private Queue queue;

@Bean
public IntegrationFlow amqpInbound(ConnectionFactory connectionFactory) {
  return IntegrationFlows.from(Amqp.inboundAdapter(connectionFactory, queue))
      .handle(m -> System.out.println(m.getPayload()))
      .get();
}

我收到错误' queueName'不能为空或空

2018-05-25 13:39:15.080 ERROR 14636 --- [erContainer#0-1] o.s.a.r.l.SimpleMessageListenerContainer : Failed to check/redeclare auto-delete queue(s).

java.lang.IllegalArgumentException: 'queueName' cannot be null or empty
    at org.springframework.util.Assert.hasText(Assert.java:276) ~[spring-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.amqp.rabbit.core.RabbitAdmin.getQueueProperties(RabbitAdmin.java:337) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.redeclareElementsIfNecessary(AbstractMessageListenerContainer.java:1604) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:963) [spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_162]

如何将消息队列名称的值设置为空字符串?

2 个答案:

答案 0 :(得分:6)

这不是一个好的解决方案。

问题在于,使用代理生成的队列名称,如果连接丢失并重新建立,队列名称将会更改,但容器将不知道新队列并将尝试从旧队列中消耗之一。

AnonymousQueue通过生成随机名称的框架解决了这个问题。

但是,匿名队列不是持久的,是独占的并且是自动删除的。

如果您希望队列具有不同的属性,但仍需要随机名称,请使用

@Bean
public Queue queue() {
  return new Queue(new AnonymousQueue.Base64UrlNamingStrategy().generateName(),
      queueDurable, queueExclusive, queueAutoDelete, queueParameters);
}

这样,如果连接丢失并重新建立,队列将获得相同的名称。

答案 1 :(得分:2)

AMQP-816问题已得到修复,现在可以在Spring Boot 2.1.0中使用。

更新项目的父项可以解决此问题:

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.1.0.RELEASE</version>
</parent>

空队列名称

spring:
    rabbitmq:
        queue:
            name:
            durable: false
            exclusive: true
            autoDelete: true

创建一个自动队列名称 amq.gen-U1vKiSfIvy8bO11jLD29Sw

Empty queue name

非空队列名称

spring:
    rabbitmq:
        queue:
            name: abc
            durable: false
            exclusive: true
            autoDelete: true

创建一个名为 abc 的队列:

Non-empty queue name