Search code examples
spring-bootdockerspring-rabbit

How to create instance specific message queues in springboot rest api


I have a number of microservices, each running in its own container in a load balanced environment. I have a need for each instance of these microservices to create a rabbitmq queue when it starts up and delete it when it stops. I have currently defined the following property in my application properties file:

config_queue: config_${PID}

My message queue listener looks like this:

public class ConfigListener {
    Logger logger = LoggerFactory.getLogger(ConfigListener.class);

    // https://www.programcreek.com/java-api-examples/index.php?api=org.springframework.amqp.rabbit.annotation.RabbitListener
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "${config_queue}",
                    autoDelete = "true"),
                    exchange = @Exchange(value = AppConstants.TOPIC_CONFIGURATION,
                    type= ExchangeTypes.FANOUT)
    ))
    public void configChanged(String message){
        ... application logic
    }
}

All this works great when I run the microservice. A queue with prefix config and process id gets created and is auto deleted when I stop the service.

However, when I run this service and others in their individual docker containers, all services have the same PID and that is 1.

Does anybody have any idea how I can create specify a queue that is unique to that instance.

Thanks in advance for your help.


Solution

  • Use an AnonymousQueue instead:

    @SpringBootApplication
    public class So72030217Application {
    
        public static void main(String[] args) {
            SpringApplication.run(So72030217Application.class, args);
        }
    
        @RabbitListener(queues = "#{configQueue.name}")
        public void listen(String in) {
            System.out.println(in);
        }
    
    }
    
    @Configuration
    class Config {
    
        @Bean
        FanoutExchange fanout() {
            return new FanoutExchange("config");
        }
    
        @Bean
        Queue configQueue() {
            return new AnonymousQueue(new Base64UrlNamingStrategy("config_"));
        }
    
        @Bean
        Binding binding() {
            return BindingBuilder.bind(configQueue()).to(fanout());
        }
    
    }
    

    AnonymousQueues are auto-delete and use a Base64 encoded UUID in the name.