Modern applications are becoming more and more complex. They have time and resource-consuming operations, communication between multiple departments, and large amounts of data processing. These are just some of the many daily problems that developers have to deal with.
But fortunately, there are solutions to all these challenges. One of them is the use of broker messages.
What is a Message Broker
A message broker is a tool/software that allows applications and systems to communicate with each other via messages. The structure of the message is formally defined and independent of the system that sends it.
This system therefore allows different applications to exchange data, even if they are built in different languages.
How message brokers work
Before we start, let's look at some basic concepts about brokers:
- Producer - The application that is responsible for sending the message. It is connected to the message broker as the publisher, in the publish/subscribe distribution pattern.
- Consumer - This is the application that is supposed to consume/receive the message. In the publish/subscribe distribution pattern, it is called subscribers.
- Queue/Topic - This is a folder in the File system. The message broker uses them to store messages.
Point-to-Point Distribution
In this pattern, there is a one-to-one relationship created between the sender and the distributor. Each message is sent and consumed only once. ย This pattern can be used for example when an action needs to be executed only once.

You're probably thinking, "OK, but what's the difference with a REST API?" The answer is quite simple. The message broker guarantees that the message will not be lost if the consumer is unavailable.
Publish/Subscribe Distribution
This pattern is a little different from the previous one. Here, the sender of the message knows nothing about the receiver. First, the messages are sent in "Topic".
After that, it is distributed among all the endpoints of other "Topic". This pattern can be interesting for implementing notification systems or can be used to build event-driven systems, for example.

Here the components are loosely coupled and pass events to each other. For example, you can have several consumers attached to a queue, where you can specify the criteria for receiving certain types of messages.
Benefits
- Providing a means of communication between services that do not have to be running at the same time. The producer can send messages regardless of whether the consumer is active or not. All it needs is to connect to the message broker. The same applies to the consumer.
- Increases system performance by introducing an asynchronous data transfer system. Very demanding tasks can be distributed between different processes. This can speed up your application and increase the user experience.
- Increased reliability by guaranteeing the transmission of messages. If a consumer is not active at the time of sending the message, then there is a guarantee that the message will be read, as it will be stored in the broker.
Drawbacks
- Increases the complexity of the application system. Introducing a message broker into the system means adding a new element to the application architecture. This leads to side effects such as maintaining security between system elements and network availability.
- Debugging can be complicated. Imagine you have several stages of asynchronous request creation using the message broker, you send something, and you don't get a response, finding the problem can be very difficult as each service has its own logs.
- There is a learning curve at the beginning. Message brokers are not as easy to understand as they seem, they have many options and configurations to set up. Tail sizes, message delivery parameters, and other such settings.
Practical Guide

Presentation
We will design the system based on 2 Spring boot applications communicating via a message broker system (Artemis ActiveMQ) following a Point-to-Point pattern. In our case, the publishers and consumers will communicate via a message queue system. And the code used to implement this system will be Java with the Spring framework.
This system ensures that messages sent by the producer will always be available to the consumer (thanks to the queues), in case the producer is unavailable.
Before you can implement this application, you will need :
- To have Maven installed ย in our local machine
- To have Java installed in our machine
Start our Artemis message broker
1. Download Artemis
In order to start our Artemis instance, we will download the broker zip file in the /opt
folder.
So move to the /opt
folder.
$ cd /opt
$ sudo wget <https://archive.apache.org/dist/activemq/activemq-artemis/2.20.0/apache-artemis-2.20.0-bin.tar.gz>
Now you will extract the tar.gz package and rename it to Artemis
$ sudo tar -xvzf apache-artemis-2.8.1-bin.tar.gz
$ sudo mv apache-artemis-2.8.1 artemis
2. Installation of Artemis
Once this is done, we will create an instance of Artemis broker.
It is recommended by Apache not to create the instance directory under the /opt/artemis
directory (which we just created). You will therefore create an instance under the /var/lib
directory. To create an instance, run the following command in your terminal:
$ cd /var/lib
$ sudo /opt/artemis/bin/artemis create broker
Once the order is initiated, you will be prompted to enter necessary information such as the user
and password
as shown below. Fill in the information to continue.

If we take a look at the directory of our newly created broker, we will see that it contains the following sub-folders
bin
: contains the execution scripts associated with this instanceetc
: contains the configuration files of the instancedata
: contains the data files used for storing messageslog
: contains the log filestmp
: contains temporary files that could be deleted without constraint.
3. Start of the Artemis instance
Once everything is OK, we can run the command to start our Artemis instance in the background
$ sudo /var/lib/broker/bin/artemis-service start
Once the broker has started, we can access its console via: http://localhost:8161/console/auth/login
After having entered the login credentials (that you defined at the broker creation) you arrive at the home page of your Artemis ActiveMQ broker console

Producer application
The producer application is the application responsible for sending the message to the broker.
Using the spring Initializr you will create a new Maven project, and extract it to a folder of your choice. Once you have done this, you can then use an IDE of your choice to open the project. (Personally, I use IntelliJ Ultimate version)
Foremost, you have to check in your pom.xml
that you have all the required dependencies
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
To begin, we will configure our application to allow its connexion to our broker
# Change application producer port
server:
port: 8081
# Broker config
spring:
activemq:
broker-url: tcp://localhost:61616
username: test
password: test
packages:
trust-all: true
artemis:
embedded:
queues: queue-data
Then enable email services for Java via Spring
@Configuration
@EnableJms
public class JmsConfig {
@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(ConnectionFactory connectionFactory) {
DefaultJmsListenerContainerFactory jmsListenerContainerFactory = new DefaultJmsListenerContainerFactory();
jmsListenerContainerFactory.setConnectionFactory(connectionFactory);
jmsListenerContainerFactory.setConcurrency("2-4");
return jmsListenerContainerFactory;
}
}
Next, we will build the structure of the message we want to send to the queue in the broker
@Getter
@Setter
@ToString
public class Message implements Serializable {
private String name;
private String email;
private String website;
}
Let's move on to the service responsible for sending the message in our queue
@Service
public class Producer {
private final JmsTemplate jmsTemplate;
private final ObjectMapper mapper;
@Value("${spring.artemis.embedded.queues}")
private String queueDestination;
public Producer(JmsTemplate jmsTemplate, ObjectMapper mapper) {
this.jmsTemplate = jmsTemplate;
this.mapper = mapper;
}
public void send(Message message) throws JsonProcessingException {
jmsTemplate.convertAndSend(queueDestination, mapper.writeValueAsString(message));
}
}
Finally, the controller that allows us to send our message via an HTTP POST
request
@RestController
@RequestMapping("/message")
public class PublisherController {
private final Producer producer;
public PublisherController(Producer producer) {
this.producer = producer;
}
@PostMapping("/publish")
public ResponseEntity<String> publish(@RequestBody Message message) {
try {
producer.send(message);
return new ResponseEntity<>("Sent", HttpStatus.OK);
} catch (Exception exception) {
return new ResponseEntity<>(exception.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
We will then start our producer application in order to play our HTTP requests, in your terminal, in the project directory, run this command to start the application:
$ mvn spring-boot:run
Let's move on to the testing phase via the Postman
tool. I personally use Postman for my REST call tests, but you can use a third party solution if you are already familiar with it.

Now if we connect to our Artemis console, we can check in the Queues
tab that the message is present


As you can see in the image above, we have our message in the broker. In the message count column, we have the number of messages sent from the producer application, waiting to be consumed by a consumer application that will be connected to our broker.
Consumer application
The consumer application is responsible for receiving/consuming the message within the broker.
As for the producer application, using the spring Initializr you will create a new Maven project, and extract it to a folder of your choice.
Foremost, you have to check in your pom.xml
that you have all the required dependencies
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
Then fill in the configuration parameters of the application
# Change application consumer port
server:
port: 8082
# Broker config
spring:
activemq:
broker-url: tcp://localhost:61616
username: test
password: test
packages:
trust-all: true
artemis:
embedded:
queues: queue-data
Finally, let's create our class that will receive/consume the messages within the queue in the broker
@Component
public class MessageConsumer {
private static final Logger LOGGER = LoggerFactory.getLogger(MessageConsumer.class);
@JmsListener(destination = "${spring.artemis.embedded.queues}")
public void messageListener(String message){
LOGGER.info("Message received, {}",message);
}
}
Now let's test our application, in your terminal, in the project directory, run this command to start the application:
$ mvn spring-boot:run
We can therefore observe below that when our application starts and is operational, it automatically receives the pending message in the broker
2022-02-21 08:48:57.454 INFO 7409 --- [ntContainer#0-1] c.demo.broker.consumer.MessageConsumer : Message received, {"name":"KOUOMEU Kevin","email":"kouomeukevin@gmail.com","website":"<https://arsenekvn.com>"}
I hope you enjoyed reading this and I'm curious to hear if this tutorial helped you.
Please let me know your thoughts in the comments section below.
Also, you can connect with me on LinkedIn or Twitter.
Talk soon
Conclusion
As you can see, message brokers are beneficial in terms of architectural flexibility.
Today we learned :
- How message brokers work
- What are the advantages of such a system, and when to use it
- How to install Apache ActiveMQ and start this service
- How you can implement this messaging system yourself with Spring boot
Checkout the code of this article here.