0
votes

I am new in Rabbitmq and I want to use single queue with multiple consumers, please help me for multiple consumers and how can we handle request for multiple consumers from single queue ?

Below is my code for Single Queue and Single Consumers

My Configuration Class

@Configuration
public class ConfigureRabbitMq {

    public static final String EXCHANGE_NAME = "mikeexchange2";
    public static final String QUEUE_NAME = "mikequeue2";


    @Bean
    Queue createQueue() {
        return new Queue(QUEUE_NAME, true, false, false);
    }

    @Bean
    TopicExchange exchange(){
        return new TopicExchange(EXCHANGE_NAME);
    }

    @Bean
    Binding binding(Queue q, TopicExchange exchange){
        return BindingBuilder.bind(q).to(exchange).with("mike.#");
    }

    @Bean
    SimpleMessageListenerContainer container(ConnectionFactory connectionFactory
            , MessageListenerAdapter messageListenerAdapter){
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueueNames(QUEUE_NAME);
        container.setMessageListener(messageListenerAdapter);
        return container;
    }


    @Bean
    MessageListenerAdapter listenerAdapter(Receive handler){
        return new MessageListenerAdapter(handler, "handleMessage");
    }
}

My Receiver Class

@Service
public class Receive {

    public void handleMessage(String messageBody){
        System.out.println("HandleMessage!!!");
        System.out.println(messageBody);
        
    }

}

My Sender Class

@RestController
public class Send {

    private final  RabbitTemplate rabbitTemplate;
    
    public  Send(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
    }
    
    
    
    @RequestMapping(method = RequestMethod.GET, value = "/api/send/{msg}")
    public String sendMessage(@PathVariable("msg") String themessage){
        
        for(int i=0;i<5000000;i++) {
            rabbitTemplate.convertAndSend(ConfigureRabbitMq.EXCHANGE_NAME,
                    "mike.springmessages", themessage+""+Integer.toString(i));
        }
        return "We have sent a message! :" + themessage;
    }
}
1
Do you mean multiple different consumers or multiple instances of the same consumer? - Nik
@Nik yes multiple difference consumers, actually when ever request receive it route to different consumers depend on load, in other words like load balancing - M Rashid
@Nik all consumers will work same, it works like load balancer, when ever request it redirect to consumer1 and conumers2 - M Rashid
I think your setup is still a bit unclear. Usually multiple consumers are realized by running multiple instances of the same service, which comes pretty close to your "load-balancing" example. However you wouldnt really have the possibility to select the instance with the least load, since there is no controlling logic. - lunatikz
Just starting multiple instances of the same component will work (assuming queues are not exclusive). However, load balancing is done in a round-robin fashion. - Nik

1 Answers

0
votes

Following your comments, you are actually kinda good to go..but like Nik said, with default configuration you are achieving loadbalancing round-robin like.

if you use spring-boot, make sure to add the dependency for spring-boot-starter-amqp.

On your receiving side, you would then generally have smth like:

@Service
public class Receive {

 @RabbitListener(queues = "<queueName>", concurrency = <numConsumersPerInstance>)
 public void handleMessage(String messageBody){
   ...
 }

Providing the concurrency parameters enables multi-threaded message consuming in one service instance. You may set this to 1, if you really want an instance consume only one message at the same time. Inspect the source code of @RabbitListener for further guidance regarding concurrency.