Spring 队列名称为空的 AMQP 入站适配器
Spring AMQP Inbound Adapter with empty queue name
我正在使用 Spring AMQP that receives messages from RabbitMQ. There is a topic exchange declared. To connect to Rabbit I create a queue with an empty name, because the broker will provide an automatic queue name, see the InterCor M4 Upgraded Specifications Hybrid specifications:
开发消费者应用程序
@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 集成 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' cannot be null or empty
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]
如何将消息队列名称的值设置为空字符串?
这不是一个好的解决方案。
问题在于,对于代理生成的队列名称,如果连接丢失并重新建立,队列名称将会更改,但容器不会知道新队列并会尝试使用来自旧的。
AnonymousQueue
通过框架生成随机名称解决了这个问题。
但是,匿名队列是不持久的,是独占的并且是自动删除的。
如果您想要一个具有不同属性的队列,但仍然想要一个随机名称,请使用
@Bean
public Queue queue() {
return new Queue(new AnonymousQueue.Base64UrlNamingStrategy().generateName(),
queueDurable, queueExclusive, queueAutoDelete, queueParameters);
}
这样,如果连接丢失并重新建立,队列将获得相同的名称。
AMQP-816 issue has been fixed and now is available in 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:
非空队列名称
spring:
rabbitmq:
queue:
name: abc
durable: false
exclusive: true
autoDelete: true
创建一个名为 abc:
的队列
我正在使用 Spring AMQP that receives messages from RabbitMQ. There is a topic exchange declared. To connect to Rabbit I create a queue with an empty name, because the broker will provide an automatic queue name, see the InterCor M4 Upgraded Specifications Hybrid specifications:
开发消费者应用程序@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 集成 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' cannot be null or empty
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]
如何将消息队列名称的值设置为空字符串?
这不是一个好的解决方案。
问题在于,对于代理生成的队列名称,如果连接丢失并重新建立,队列名称将会更改,但容器不会知道新队列并会尝试使用来自旧的。
AnonymousQueue
通过框架生成随机名称解决了这个问题。
但是,匿名队列是不持久的,是独占的并且是自动删除的。
如果您想要一个具有不同属性的队列,但仍然想要一个随机名称,请使用
@Bean
public Queue queue() {
return new Queue(new AnonymousQueue.Base64UrlNamingStrategy().generateName(),
queueDurable, queueExclusive, queueAutoDelete, queueParameters);
}
这样,如果连接丢失并重新建立,队列将获得相同的名称。
AMQP-816 issue has been fixed and now is available in 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:
非空队列名称
spring:
rabbitmq:
queue:
name: abc
durable: false
exclusive: true
autoDelete: true
创建一个名为 abc:
的队列