rabbitmq 为每个队列创建单独的容器

csbfibhn  于 2022-11-08  发布在  RabbitMQ
关注(0)|答案(1)|浏览(223)

我有一个使用案例,其中我们严格要求所有队列都有一个专用线程和消费者,这意味着每个线程只服务一个队列。
我已经阅读了Gary Russell给出的答案和评论。他提到要创建一个子应用程序上下文来拥有@RabbitListener的所有特性,以实现我正在尝试的功能。但我仍然不知道如何在运行时动态添加队列时做到这一点。
如果可能的话,请给我指一下相关的文章,以解决这个问题,包括应用程序上下文的方式(以及如何创建子上下文)和建议的MessageListenerAdapter方式。

z5btuh9x

z5btuh9x1#

下面是一些基于Spring Boot和子应用程序上下文声明的解决方案。
1.我在组件中有@RabbitListener,它将在子上下文中声明:

@EnableRabbit
 public class DynamicRabbitListener {

     @Bean
     public AmqpAdmin amqpAdmin(ConnectionFactory connectionFactory) {
         return new RabbitAdmin(connectionFactory);
     }

     @RabbitListener(queuesToDeclare = @Queue(name = "${dynamic.queue}", autoDelete = "true"))
     public void listen(String payload, @Header(AmqpHeaders.CONSUMER_QUEUE) String queueName) {
         System.out.printf("Received %s from queue %s%n", payload, queueName);
     }

 }

1.我们需要@EnableRabbit将各自的注解处理器注册到子应用程序上下文,并能够触发适当的生命周期。

  1. W在此上下文中需要AmqpAdmin,以便能够声明动态队列。
    1.这两个方面在处理和逻辑上都给了我们一些隔离。
    1.下面是我声明这些上下文的方式:
@Bean
 ApplicationRunner applicationRunner(ConfigurableApplicationContext parent, RabbitTemplate rabbitTemplate) {
     return args -> {
         for (int i = 0; i < 10; i++) {
             String dynamicQueue = "dynamicQueue#" + i;
             AnnotationConfigApplicationContext childApplicationContext =
                     new AnnotationConfigApplicationContext();
             childApplicationContext.setParent(parent);
             childApplicationContext.register(DynamicRabbitListener.class);

             ConfigurableEnvironment environment = parent.getEnvironment();
             MapPropertySource propertySource =
                     new MapPropertySource("dynamic.queues", Map.of("dynamic.queue", dynamicQueue));
             environment.getPropertySources().addLast(propertySource);
             childApplicationContext.setEnvironment(environment);

             childApplicationContext.refresh();

             rabbitTemplate.convertAndSend(dynamicQueue, "test data #" + i);
         }
     };
 }

注意propertySource要实现一个动态的要求,对于每个子应用程序上下文都有其特定的@RabbitListener
我的程序的输出是这样的:

.   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.7.0)

Received test data #0 from queue dynamicQueue#0
Received test data #1 from queue dynamicQueue#1
Received test data #2 from queue dynamicQueue#2
Received test data #3 from queue dynamicQueue#3
Received test data #4 from queue dynamicQueue#4
Received test data #5 from queue dynamicQueue#5
Received test data #6 from queue dynamicQueue#6
Received test data #7 from queue dynamicQueue#7
Received test data #8 from queue dynamicQueue#8
Received test data #9 from queue dynamicQueue#9

相关问题