Create work(s) queue with SpringBoot and RabbitMQ

Chung Khanh Duy
3 min readJul 4, 2018

--

Some time you need to design a work(task) queue to processing your dataset. The task queue approach is useful when your system probably receive a lot of requests at the same time and you don’t need to response them immediately, then you put each request in queue and process them sequently. There are a lot use cases that you can apply task queue in real projects. So hopefully the article will help to get you understand and basically set up the task queue for your different purposes.

But wait… If you’re lazy to read, here is full video to demonstrate how to do https://www.youtube.com/watch?v=gGL0e0KvREE&feature=youtu.be, you can take a look without continue reading :)

  1. Install RabbitMQ, this installation guidance used for MacOS only, depend on your OS , you can find out how to install RabbitMQ. Here is the official site: https://www.rabbitmq.com/download.html

brew install rabbitmq

Default rabbitMQ server was not in your class path , so you need to set it up manually in order to easily to kick it off. RabbitMQ was installed in /usr/local/sbin folder and you need to set path for it in ~/.bash_profile. Please remember refresh your bash profile after setting.

PATH=$PATH:/usr/local/sbin

Then run rabbitMQ server by command line:

rabbitmq-server

The screenshot of terminal looks like:

2. Add springboot-starter-amqp library in your project, I’m using gradle to build project so here is what I added in .gradle file ( you can easily find it in maven repository with using maven instead )

compile “org.springframework.boot:spring-boot-starter-amqp”

3. Create a Configuration for SpringBoot, I named it as ‘RabbitConfiguration’:

package com.example.spring.rabbitmq.config;

import org.springframework.amqp.core.Queue;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

import com.example.spring.rabbitmq.service.TaskReceiver;
import com.example.spring.rabbitmq.service.TaskSender;

@Configuration
public class RabbitMQConfiguration {

@Bean
public Queue hello() {
return new Queue("hello");
}

private static class ReceiverConfig {

@Bean
public TaskReceiver receiver() {
return new TaskReceiver();
}

}

}

In this configuration we create a queue ‘hello’ and used this queue to persist your waiting task. Then TaskReceiver will pick up the task from queue and process. In this example I just demonstrate sending a few message ‘hello’ task and check if receiver can listen and pick up message and process message. The method doWork() sleep for awhile to demo processing something when receiving message. Note that you have to mention correctly queue name in @RabbitListener

TaskReceiver.java

package com.example.spring.rabbitmq.service;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.util.StopWatch;

@RabbitListener(queues = "hello")
public class TaskReceiver {

@RabbitHandler
public void receive(String in) throws InterruptedException {
StopWatch watch = new StopWatch();
watch.start();
System.out.println(" [x] Received '" + in + "'");
doWork(in);
watch.stop();
System.out.println(" [x] Done in " + watch.getTotalTimeSeconds() + "s");
}

private void doWork(String in) throws InterruptedException {
for (char ch : in.toCharArray()) {
if (ch == '.') {
Thread.sleep(1000);
}
}
}
}

TaskSender.java: This service used to demonstrate send some tasks (message ) to queue and listener will pickup later. @PostContruct will help to execute send() method automatically when init service.

@Service
public class TaskSender {

@Autowired
private RabbitTemplate template;

@Autowired
private Queue queue;

@PostConstruct
public void send() {
try {
for (int i = 0; i < 5; i++) {
String message = "hello" + i;
template.convertAndSend(queue.getName(), message);
System.out.println(" [x] Sent '" + message + "'");
}
} catch (Exception e) {
e.printStackTrace();
}
}

}

4. You also need to provide connection information in your .yml file to help springboot-start-amqp connect to RabbitMQ:

rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest

Now you can run your SpringBoot app and result should looks like:

Demo sent 5 messages which represent for 5 tasks and listener will pick up 5 tasks from queue and process. Note that you can send any Object instead depend your complexity of the task.

Full source code here: https://github.com/duymap/spring-rabbitmq-workqueue

Please clap if you like this post ^_^

--

--

Chung Khanh Duy

Solution Architect | SW Engineer | A Husband | A Father | A person who loves to build software