Express Servers communicating through RabbitMQ
Wajiha Abid
Software Engineer | Nodejs | Typescript | GraphQL | Socket.io | Laravel | React/Vue | Freelancer
WHAT IS RABBITMQ?
RabbitMQ is?a message broker . It gives your applications a common platform to send and receive messages, and your messages a safe place to live until received. You can use it for caching, realtime updates etc.
Pre-requisites:
HOW TO SETUP RABBITMQ IN WINDOWS:
You can download the rabbitMQ server in your machine, then install and run to use it locally. Another method is that we can pull the docker image and use it. Following are steps to run the rabbitMQ docker image:
docker pull rabbitmq:3-management
2. Run the image to use it, do specify the name of it when running it:
docker run -d -p 15672:15672 -p 5672:5672 --name [your-name] rabbitmq:3-management
3. Check is it running or not:
docker images
Above command will give the following list
Default port for rabbitMQ is 15672, so on running the url 'https://localhost:15672' it will render the GUI for RabbitMQ Management. It will ask for username and password, for guest user both the username and password is "guest". Here you can monitor all the connections, channels and queues.
ARCHITECTURE DIAGRAM:
The flow of the communication will be like this. Producer will send the message to the queue. Consumer will be listening throughout the queue. As the queue got the message, consumer will extract it.
To implement this architecture, we need 3 simple steps which are mentioned below:
领英推荐
STEP 1:
Lets configure the two express servers. One named as Producer and other named as Consumer.
Install the rabbitmq package in both servers with following command.
npm i?amqplib
Make a connection to the rabbitmq server as following on both the nodejs servers:
const mq = require('amqplib/callback_api')
l
let queue = "myMsg"
//rabbitmq connection
mq.connect({
? ? username: process.env.USERNAME,
? ? password: process.env.PASSWORD
}, (err, con) => {
? ? if (err)
? ? ? ? throw err
? ? //create channel
? ? con.createChannel((err, channel) => {
? ? ? ? if (err)
? ? ? ? ? ? throw err;
? ? ? ? //create queue,if not exist
? ? ? ? channel.assertQueue(queue, {
? ? ? ? ? ? durable: false
? ? ? ? })
? ? ? ?
? ? })
}))
STEP 2:
Now move to producer server and make a function to publish the message to the queue. And assign the channel to any variable to access it in the function. Now the connection file of producer will look like this:
**/Production server
const mq = require('amqplib/callback_api')
let myChannel = null;
let queue = "myMsg"
//rabbitmq connection
mq.connect({
? ? username: process.env.USERNAME,
? ? password: process.env.PASSWORD
},
(err, con) => {
? ? if (err)
? ? ? ? throw err
? ? //create channel
? ? con.createChannel((err, channel) => {
? ? ? ? if (err)
? ? ? ? ? ? throw err;
? ? ? ? //create queue,if not exist
? ? ? ? channel.assertQueue(queue, {
? ? ? ? ? ? durable: false
? ? ? ? })
? ? ? ? myChannel = channel
? ? })
})
//send the msg to the consumer
const publishToQueue = async (data) => {
? ?
? ? //send data to the queue
? ? myChannel.sendToQueue(queue, Buffer.from(data))
}
module.exports = { publishToQueue }
Now configure a route in server.js for publishing a message to the queue.
**/Production server
//route to send the msg to the queue
app.get("/send/:msg", async (req, res) => {
? ? try {
? ? ? ? await publishToQueue(req.params.msg);
? ? ? ? return res.status(200).json({ msg: "Send to the queue" })
? ? } catch (err) {
? ? ? ?
? ? ? ? return res.status(400).json(err)
? ? }
})
STEP 3:
Lets configure the consumer now, which will listen to the queue and console the message. 'noAck' option is set to false as for now on testing I dont want the data to be lost after recieved. But for production it should set to be true, so that data should be cleared from queue as soon as it is recieved.
**/Consumer server
//listening to the queue
? channel.consume(queue, function (msg) {
? ? ? console.log("[Publisher]:", msg.content.toString());
?}, {
? ? ? noAck: false
? });
Finally both the Production and consumer are set. Run both servers and hit the API from producer server to publish a message. In consumer server, you can see the same message which you have send through API.
WHY I USED RABBITMQ?
I had two scenarios which is covered through rabbitMQ.
CONCLUSION:
RabbitMQ is easy to use and good for mid-level applications. We have more brokers like Apache, Redis etc and they have their own pros and cons. For my scenario, rabbitMQ looks better choice so it also depends on the use case. For complete code, checkout this repo, and share the use case for which you have used it.
Thanks for reading!