Joy
Joy

Reputation: 4463

Processing message from rabbitmq at specified rate

We have been trying to make listener read messages from rabbitmq at a certain rate 1 msg/2 seconds. We did not find any such utility with rabbit mq so far. So thought of doing this with DB i.e. listener will read the messages and store it into DB and later a scheduler will process at that desired rate from DB. If there is any better way of doing this, please suggest. We are developing our application in Spring. Thanks in advance.

Upvotes: 1

Views: 1080

Answers (2)

Dherik
Dherik

Reputation: 19050

Inspired on the Gary Russel answer:

you can use something more sophisticated like a task scheduler or a Spring @Async

You can also get a number of determined message per minute and simulate the same limit rate:

private final RabbitTemplate rabbitTemplate;

@Scheduled(fixedDelay = 60000) // 1 minute
public void read() {

    List<String> messages = new ArrayList<>();
    String message = getMessageFromQueue();
    while(message != null && messages.size() < 30) { // 30 messages in 1 minute = 1 msg / 2 seconds
        messages.add(message);
        message = getMessageFromQueue();
    }

    public String getMessageFromQueue() {
        return (String) rabbitTemplate.receiveAndConvert(QUEUE_NAME);
    }

}

Upvotes: 0

Gary Russell
Gary Russell

Reputation: 174494

You can't do it with a listener, but you can do it with a RabbitTemplate ...

@SpringBootApplication
public class So40446967Application {

    public static void main(String[] args) throws Exception {
        ConfigurableApplicationContext context = SpringApplication.run(So40446967Application.class, args);
        RabbitAdmin admin = context.getBean(RabbitAdmin.class);
        AnonymousQueue queue = new AnonymousQueue();
        admin.declareQueue(queue);
        RabbitTemplate template = context.getBean(RabbitTemplate.class);
        for (int i = 0; i < 10; i++) {
            template.convertAndSend(queue.getName(), "foo" + i);
        }
        String out = (String) template.receiveAndConvert(queue.getName());
        while (out != null) {
            System.out.println(new Date() + " " + out);
            Thread.sleep(2000);
            out = (String) template.receiveAndConvert(queue.getName());
        }
        context.close();
    }

}

Of course you can use something more sophisticated like a task scheduler or a Spring @Async method rather than sleeping.

Upvotes: 1

Related Questions