Spring 2.1.0.M4 RabbitMQ声明队列并将其绑定到运行时中的侦听器

时间:2018-10-14 19:13:42

标签: java spring spring-boot rabbitmq spring-rabbitmq

假设我有一个已声明的侦听器:

Listener.java

@RabbitListener(id = "test listener 1")
    public String test2(String req) {
        return req + " result";
}

我正在尝试在运行时通过队列公开它:

ListenerTest.java

Queue declaredQueue = new Queue("new.queue", false);

admin.declareQueue(declaredQueue);

SimpleMessageListenerContainer listener = (SimpleMessageListenerContainer) 
            registry.getListenerContainer("test listener 1");
listener.addQueues(declaredQueue);

然后我尝试向新声明的队列发送消息:

String result = template.convertSendAndReceiveAsType("new.queue", "req", ParameterizedTypeReference.forType(String.class));

但是它只是超时并返回null。

在调试器中检查侦听器时,看不到绑定到新队列enter image description here的任何使用者”

您可以通过Rabbit配置here找到其余的源代码来测试此here

值得注意的是,此确切设置可在春季启动版本 2.0.5.RELEASE 中使用,因此可能是一个错误。我需要找到一种重新初始化消费者的方法。

2 个答案:

答案 0 :(得分:1)

在运行时添加队列将导致容器回收其使用者(等同于停止并重新启动容器)。参见https://github.com/spring-projects/spring-amqp/blob/master/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/SimpleMessageListenerContainer.java#L687,这是由于消费者的设计方式所致。每个使用者线程都从多个队列中消费。

更改使用者数量并不会重新启动所有使用者;参见https://github.com/spring-projects/spring-amqp/blob/master/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/SimpleMessageListenerContainer.java#L168

添加队列后,新的DirectMessageListenerContainer不需要重新启动其使用者(每个队列至少有一个使用者)。

但是,它不支持动态并发扩展。

答案 1 :(得分:0)

2.1.0发行版之后,SELECT * FROM table WHERE (a, b) IN (VALUES (23, ARRAY[1]),(20, ARRAY[0]),(17, ARRAY[-1,0,1]),(55, ARRAY[-1, 0])) 不再覆盖SimpleMessageListenerContainer,这将导致AbstractMessageListenerContainer#addQueues不被调用(可能是错误)。但是SimpleMessageListenerContainer#queuesChanged被覆盖并且可以正常工作。因此,必须将其更改为

SimpleMessageListenerContainer#addQueueNames

或者SimpleMessageListenerContainer listener = (SimpleMessageListenerContainer) registry.getListenerContainer("test listener 1"); listener.addQueueNames(declaredQueue.getName()); 必须手动调用

queuesChanged