The Talent500 Blog
rabbitMQ

Introduction and Understanding – RabbitMQ

Introduction

Imagine yourself going to PVR to purchase a movie ticket. There is a very large queue for the show you want to watch when you get to the theatre. How lengthy the queue is and how patient you are will determine whether or not you get to see the film at this point. You might wish to watch it later if the queue is too long or if you have to wait too long. However, if PVR had more ticket counters, the queue and waiting time would disappear. This is what a queue looks like in the context of system design. 

Systems that can process large amounts of data and requests in a timely manner are becoming increasingly vital in today’s rapidly evolving software development landscape. Distributed components can now collaborate seamlessly and effectively through message-based communication between applications. However, the TTL of these message-based interactions is finite in the context of application computing. Processing time for synchronous communications often varies with the speed of the executing application. 

As a result, asynchronous communication is the norm in the modern world. That processing unit then receives the message and stores it while it waits for additional processing. For instance, when attempting to retrieve a six-month archive of one’s bank statements. The request becomes a job that is sent to a worker node to be completed. In a scenario where the worker node is busy processing something else, the job waits in the queue for its availability. 

As an open-source message broker, RabbitMQ facilitates the safe and prompt exchange of information. Developers and architects alike now turn to RabbitMQ when they need to create scalable, reliable, and modern distributed systems that can manage complex workflows. In this post, we’ll discuss RabbitMQ, a popular messaging queue, and learn how to utilize RabbitMQ to construct dependable and scalable distributed systems by diving deep into its features, ideas, use cases, best practices, and real-world examples.

Introduction and Understanding - RabbitMQ 1

Uses of Queues

Modern software architecture relies on queues for asynchronous communication and distributed workload control. Software architecture commonly uses queues:

  • Message/Event-driven architectures use queues for communication. Asynchronous systems consume messages/events from a queue. This lets systems to communicate asynchronously and loosely, enabling scalability.
  • Load balancing: Queues distribute burden across multiple processing units. In a distributed system with numerous worker nodes, jobs can be queued and processed by worker nodes. Load balancing prevents nodes from overloading and distributes duties evenly across workers.
  • Distributed systems can handle failures with queues. Messages/events can be queued until a system or component recovers. This gracefully handles failures and protects data and tasks.
  • Queues handle rising loads in horizontally scalable systems. Tasks or requests can be queued and processed at a system’s capacity as load grows. This provides workload-based scaling.
  • Microservices architectures: Queues facilitate microservice communication. Asynchronous microservices can consume messages/events from a queue. This lets microservices develop, launch, and scale independently.
  • Queues can cache data or results for later processing. In a system with significant computing or data processing, intermediate results can be placed in a queue and processed by numerous consumers, decreasing the strain on the primary processing component.
  • Event sourcing and event-driven architectures: Queues capture and process events. Event consumers can handle queued events asynchronously, enabling real-time event processing and event-driven processes.

Introduction and Understanding - RabbitMQ 2

What is AMQP?

AMQP is an acronym for Advanced Message Queuing Protocol. It is an open-standard messaging protocol that enables the coordination and communication of messages between distributed applications or systems. AMQP is intended to provide a dependable, secure, and efficient method for exchanging messages between distributed system components.

AMPQ is a package of information

  • Header (key-value pair)
  • Properties
  • Body (payload, actual message)

Introduction and Understanding - RabbitMQ 3

AMQP is based on a client-server architecture in which applications or systems can function as either message producers or message consumers. Producers generate and send messages to message brokers, while consumers receive and process messages from brokers. Message brokers are accountable for the routing, storage, and delivery of communications to their intended recipients.

AMQP provides a comprehensive set of features that make it suitable for a variety of messaging scenarios, such as:

  1. AMQP supports a variety of message exchange patterns, such as point-to-point, publish/subscribe, request/reply, and fanout, enabling flexible and efficient message routing.
  2. AMQP ensures message delivery reliability by supporting acknowledgements, confirmations, and transactions, thereby facilitating robust and error-tolerant messaging.
  3. AMQP supports message prioritisation, allowing applications to designate distinct priorities for messages and control their processing sequence.
  4. AMQP supports durable messages, which are maintained even if the broker or recipient application fails, thereby assuring message durability and preventing data loss.
  5. AMQP provides built-in support for secure communication via authentication, authorization, and encryption, ensuring the security of messages in transit.
  6. AMQP is designed to be language- and platform-agnostic, enabling applications written in different programming languages and operating on different platforms to communicate seamlessly.
  7. Scalability: AMQP is designed for scalable messaging, permitting the distribution of messages across multiple brokers and the use of various message patterns to scale up or down based on the system’s requirements.
  8. AMQP is utilised in a variety of applications and industries, including finance, healthcare, e-commerce, IoT, and telecommunications. It is supported by prominent messaging brokers including RabbitMQ, Apache ActiveMQ, and Apache Qpid.

Introduction and Understanding - RabbitMQ 4

Why use RabbitMQ?

RabbitMQ is a well-known open-source message broker that is widely utilised and plays an important part in the development of contemporary software. It promotes the decoupling of applications, improves scalability, and enhances dependability in distributed systems by providing a robust and scalable messaging solution.

  1. The standard distribution of RabbitMQ includes plugins that support a variety of protocols, including Streaming Text Oriented Messaging Protocol (STOMP), Message Queuing Telemetry Transport (MQTT), and others. RabbitMQ is compatible with plugins.
  2. Asynchronous messaging lets RabbitMQ decouple applications. Producers and consumers can handle RabbitMQ messages at their own pace. Decoupling lets apps develop, launch, and scale independently, making them more agile and change-resistant.
  3. Horizontal scalability: RabbitMQ allows several producers and consumers to interact with the message broker simultaneously. Distributed systems can achieve high throughput and low latency by sharing workload among numerous processing units. RabbitMQ’s support for publish/subscribe and fanout message exchange patterns allows efficient message routing and scaling based on system demands.
  4. Acknowledgements, confirmations, and transactions make RabbitMQ dependable. RabbitMQ sends acknowledgements to producers when messages are received, and consumers can confirm message processing. RabbitMQ offers persistent messages that persist even if the broker or recipient application fails, preventing data loss.
  5. Microservices designs employ RabbitMQ to communicate between microservices. Microservices can independently develop, launch, and scale by producing and consuming RabbitMQ messages. In microservices architectures, RabbitMQ supports request/reply and event-driven processes.
  6. Event-driven systems: RabbitMQ works well for constructing real-time event-driven systems. RabbitMQ supports message exchange patterns, event prioritisation, durability, and security. RabbitMQ is popular for scalable and dependable event-driven systems.
  7. Asynchronous processing: RabbitMQ lets producers transmit messages without rapid answers and consumers process them on their own time. This lets background workers handle time-consuming activities, letting the main application keep fulfilling user requests.

Understanding RabbitMQ Concepts

RabbitMQ helps distributed system producers and consumers communicate. Several key elements enable reliable messaging:

  • Producers: RabbitMQ receives messages from producers. Producers send RabbitMQ messages. Text, JSON, or binary messages can carry any information between programs.
  • Exchanges: RabbitMQ exchanges route messages. They route producer messages to queues using defined routing rules. RabbitMQ enables direct, fanout, topic, and header exchanges to route messages to queues.
  • Queue: RabbitMQ queues keep messages until consumers consume them. Consumers process queued communications. RabbitMQ queues can have durability and exclusivity (only one consumer can use the queue at a time), and auto-deletion (queue is removed when no longer in use).
  • Consumers: Consumers receive and process queued communications. Queues send messages to subscribers. The application determines whether consumers process messages synchronously or asynchronously.

Introduction and Understanding - RabbitMQ 5

Installation of RabbitMQ

Step 1: Install and Configure RabbitMQ

Download and install RabbitMQ from the official RabbitMQ website (https://www.rabbitmq.com/).

Start the RabbitMQ server, which runs as a standalone service.

Access the RabbitMQ management console using a web browser, typically available at http://localhost:15672/. Log in with the default credentials (username: guest, password: guest).

Optionally, create virtual hosts, and users, and set permissions in the RabbitMQ management console to control access to RabbitMQ resources.

Step 2: Create a Producer in Python

  • Install the RabbitMQ Python client library, such as “pika”, using a package manager like pip.
  • Import the “pika” library in your Python script.
  • Create a connection to the RabbitMQ server using the “pika” library.
  • Declare an exchange and a queue using the “pika” library.
  • Publish messages to the exchange using the “pika” library, specifying the routing key and message body.

Example Python code for creating a RabbitMQ producer:

import pika

# Connect to RabbitMQ server

connection = pika.BlockingConnection(pika.ConnectionParameters(‘localhost’))

channel = connection.channel()

# Declare an exchange

channel.exchange_declare(exchange=’my_exchange’, exchange_type=’direct’)

# Declare a queue

channel.queue_declare(queue=’my_queue’)

# Publish a message to the exchange

channel.basic_publish(exchange=’my_exchange’, routing_key=”, body=’Hello, RabbitMQ!’)

# Close the connection

connection.close()

Step 3: Create a Consumer in Python

  • Install the RabbitMQ Python client library, such as “pika”, using a package manager like pip.
  • Import the “pika” library in your Python script.
  • Create a connection to the RabbitMQ server using the “pika” library.
  • Define a callback function to handle received messages.
  • Consume messages from the queue using the “pika” library, specifying the callback function.

Example Python code for creating a RabbitMQ consumer:

import pika

# Define the callback function to handle received messages

def callback(ch, method, properties, body):

    print(“Received message: %r” % body)

# Connect to RabbitMQ server

connection = pika.BlockingConnection(pika.ConnectionParameters(‘localhost’))

channel = connection.channel()

# Declare a queue

channel.queue_declare(queue=’my_queue’)

# Consume messages from the queue and pass them to the callback function

channel.basic_consume(queue=’my_queue’, on_message_callback=callback, auto_ack=True)

# Start consuming messages

channel.start_consuming()

Step 4: Send and Receive Messages

  • Launch the RabbitMQ producer script to communicate with the market.
  • To read messages from the queue, trigger the RabbitMQ consumer script.
  • To view the published and consumed messages, log onto the RabbitMQ administration console.

This is just a very basic producer-consumer scenario demonstrating how RabbitMQ can be used. Additional options, such as message durability, message acknowledgements, error handling, and scalability, may be required in practical situations.

WEB UI Console Screenshots show, Overview, Connections, Channels, Exchanges, Queues and Admin Console.

Introduction and Understanding - RabbitMQ 6

Introduction and Understanding - RabbitMQ 7

Introduction and Understanding - RabbitMQ 8

Introduction and Understanding - RabbitMQ 9

Configuration

RabbitMQ provides three general ways to customise the node:

  • Environment variables – define ports, file locations and flags (taken from the shell, or set in the

environment configuration file,rabbitmq-env.conf/rabbitmq-env-conf.bat)

  • Configuration file – defines server component settings for permissions, limits and clusters, and well as plugin settings
  • Runtime parameters and policies – defines cluster-wide settings which can change at run time

Most important config file entries

  • cluster_name (default “”) – used for automatic clustering
  • listeners.tcp.default – same as RABBITMQ_NODE_PORT
  • heartbeat (default 60 seconds) – after 60s connection should be considered unreachable by RabbitMQ and client libraries. Server suggest this value to client libraries while establishing TCP connection at AMQP protocol level. Clients might not follow the server’s suggestion.
  • frame_max – (default 131072) – maximum permissible size of a frame (in bytes) to negotiate with clients (AMQP protocol level). Larger value improves throughput, smaller value improves latency (not related with max message size which is 2GB)
  • channel_max – (default 0 – unlimited) – number of channels to negotiate with clients. Using more channels.increases broker’s memory footprint,
  • management.tcp.port (default 15672) – the web-management and RESTful service

RabbitMQ Ports:

4369: epmd, a peer discovery service used by RabbitMQ nodes and CLI tools

5672, 5671: used by AMQP 0-9-1 and 1.0 clients without and with TLS

25672: used by Erlang distribution for inter-node and CLI tools communication and is allocated from a dynamic range (limited to a single port by default, computed as AMQP port + 20000).

15672: HTTP API clients and rabbitmqadmin (only if the management plugin is enabled)

Other protocols:

61613, 61614: STOMP clients without and with TLS (only if the STOMP plugin is enabled)

1883, 8883: MQTT clients without and with TLS, (only if the MQTT plugin is enabled)

15674: STOMP-over-WebSockets clients (only if the Web STOMP plugin is enabled)

15675: MQTT-over-WebSockets clients (only if the Web MQTT plugin is enabled)

Core Concepts: 

RabbitMQ Message Flow

  1. Producer emits messages to exchange
  2. Consumer receives messages from the queue 
  3. The queue keeps/stores messages
  4. Binding: A binding is a relationship between an exchange and a queue that defines how messages should be routed from the exchange to the queue. Bindings are created based on routing keys or headers, and they determine which messages are delivered to which queues. Exchange Binding connects an exchange with a queue using a binding key. Exchange compares the routing key with the binding key (on-to-one or using a pattern)

Exchanges

  • The exchange type determines the distribution model
  • Exchange types: nameless (empty string – default one), fanout, direct, topic, headers

Default: Nameless exchange (aka “default exchange”, aka “AMQP default”)

  • Special one created by RabbitMQ
  • Compares routing key with the queue name
  • Allows sending messages “directly” to the queue (from the publisher’s perspective exchange is transparent)

Different types of exchanges in RabbitMQ are used for different routing scenarios:

Direct exchange: Messages are routed to queues based on a direct routing key that matches the routing key specified by the producer. This is a one-to-one routing pattern where messages with a specific routing key are routed to a specific queue.

Fanout exchange: Messages are broadcast to all queues that are bound to the fanout exchange. This is a one-to-many routing pattern where messages are sent to all bound queues, making it suitable for scenarios where multiple consumers need to receive the same message.

Topic exchange: Messages are routed to queues based on a pattern in the routing key specified by the producer. This allows for flexible and powerful routing based on wildcards and patterns in routing keys, making it suitable for scenarios where messages need to be selectively routed to multiple queues based on different criteria.

Headers exchange: Messages are routed to queues based on the values in the message headers. This allows for complex routing based on header attributes, making it suitable for scenarios where messages need to be routed based on specific header values.

These exchange types provide flexibility and versatility in routing messages in RabbitMQ, allowing for various use cases and messaging patterns in distributed systems.

Queue

A queue is located on a single node where it is declared and referenced by a unique name, in contrast to exchanges and bindings which exist on all nodes. The name of the queue can be provided by the user or auto-generated by RabbitMQ. Both producers and consumers can create a queue.

Performance-wise, each queue corresponds to one Erlang process. When a node starts, up to 16384 messages are loaded into RAM from the queue, which can impact performance.

A queue is an ordered collection of messages. Messages are published and consumed in a First-In, First-Out (FIFO) manner, except for prioritized queues which may have different behavior.

A queue has many properties that can be configured based on the use case. These properties determine the behavior of the queue, such as durability, exclusivity, and more.

Queues can be federated or mirrored to increase reliability and availability in a distributed system.

Internal queues with names prefixed by “amq.” are used for RabbitMQ internal purposes only and are not meant for general application use.

Queue Properties:

Name: The name of the queue can be provided by the user or auto-generated by RabbitMQ.

Deletion: The auto-delete feature allows a queue to delete itself when all consumers disconnect.

Classic or Quorum: Queues can be classic or quorum, where quorum and mirroring policies increase availability in distributed systems.

Exclusive: Exclusive queues are used by only one connection and are deleted when that connection closes.

Priority: Setting priority for queues adds additional CPU cost and increased latency, and there is no guarantee of exact order, only a strong suggestion.

TTL: Queues and messages can have an expiration time (TTL) specified using policy settings. The minimum value from both messages (using the expiration property) and queues (using x-message-ttl) is used.

Message Acknowledgments: RabbitMQ allows consumers to send acknowledgments (or “acks”) to the broker after successfully processing a message. This feature ensures that messages are not lost even if a consumer crashes or fails during message processing. If a consumer fails to send an ack within a configured timeout, RabbitMQ can re-queue the message for another consumer to process. This helps in achieving reliable message delivery and prevents message loss in case of failures.

Message Durability: RabbitMQ allows messages to be marked as durable, which means that they will be persisted to disk and survive broker restarts. This ensures that messages are not lost even if the broker goes down or restarts, making RabbitMQ more reliable in handling message processing in distributed systems.

Dead-Letter Exchanges: RabbitMQ allows the use of dead-letter exchanges, which are special exchanges where messages can be routed if they are rejected, expired, or fail to be delivered to their intended queues. This allows for graceful handling of failed messages and provides a mechanism for error handling and error recovery in the messaging system.

RabbitMQ Best Practices:

It is crucial to adhere to best practises while implementing RabbitMQ in production systems, as this will guarantee consistent and efficient message processing. Here are some recommendations and guidelines for making the most of RabbitMQ:

  • Handling issues Right: Make sure your consumers have solid error handling methods in place to deal with situations like network outages, message processing issues, and exceptions. Errors and failures should be recorded so that they can be reviewed and investigated later. Dead-letter exchanges could be used to gracefully handle failed messages and provide error recovery capabilities.
  • Select a suitable serialisation format for your communications to guarantee portability across languages and platforms. Formats like JSON, XML, and Protobuf are commonly used for serialisation. For error-free message processing, check that your messages are serialised and deserialized correctly.
  • RabbitMQ monitoring and alerting allows you to keep tabs on your messaging system’s health and performance. Use monitoring software or RabbitMQ management plugins to keep tabs on vital statistics like message throughput, queue size, consumer and broker health. In this way, any problems with the system’s performance or dependability can be found and fixed immediately.
  • Boost your RabbitMQ’s performance by fine-tuning its settings. Adjusting the number of messages prefetched, the size of the connection pool, and the amount of memory allocated to RabbitMQ may be necessary depending on the demands placed on the system. To reduce needless message processing overhead and maximise efficient message routing, it is important to use the correct exchange kinds and routing patterns.
  • Use many exchanges, queues, and consumers together with other relevant RabbitMQ features to design a scalable and robust system. To guarantee the consistency and dependability of your messages, think about employing publisher confirms or transactions. If you want messages and queues to persist through broker restarts, use durability. Spreading users out across several nodes improves availability and resilience.
  • When working with RabbitMQ, it’s important to avoid falling into any of the frequent mistakes users have encountered before. Message replication and mirrored queues are two features that might negatively affect performance, so avoid using them unless absolutely essential. Avoid extra processing time by being cautious of how you route and bind messages to queues.
  • Authentication and authorisation procedures, as well as protected access to administration interfaces, should be enabled and SSL/TLS encryption should be used for all communication sent over RabbitMQ. Keep RabbitMQ up-to-date and patched on a regular basis to ensure its continued security and protection from exploits.
  • Perform extensive load tests, failure simulations, and edge case testing on your RabbitMQ-based system. Keep an eye on the system as it goes live so that any problems may be addressed without delay.

By adhering to these guidelines, you can be sure that RabbitMQ is being used properly in your production systems, maximizing its potential for efficient and scalable message processing and robustness. If you want RabbitMQ to operate well and be reliable in your system, you need to configure and use it in a way that takes those factors into account.

Conclusion

In conclusion, RabbitMQ is a robust and popular open-source message broker for dependable distributed system messaging and communication. It promotes scalability, dependability, decoupling, and asynchronous processing in distributed systems. It supports microservices architecture, event-driven systems, and asynchronous processing through decoupling apps, asynchronous processing, and alternative message patterns.

Readers are urged to look into RabbitMQ for software development initiatives. The official RabbitMQ documentation (https://www.rabbitmq.com/docs.html) covers ideas, features, and usage. To gain experience, they can install and configure RabbitMQ, create producers and consumers in different programming languages, and send/receive messages between applications. 

 

0
Shubham Singh

Shubham Singh

He is a SDE-2 DevOps Engineer, with demonstrated history in working with scaling startup. A problem solver by mettle, who loves watching anime when he is not working. He is a learner and educator by heart.

Add comment