We are all familiar with Hogwarts' magical postal network, the
  Owl Post Office. This magical delivery system relies on owls to deliver
  packages and letters. They can even pick up an item from any address and give
  it to another using their magical tracking abilities. Similarly, we can
  compare RabbitMQ, a message broker to the Owl Post Office. It allows applications
  to interact with one another and exchange messages.
But why should we use message broker?
  An e-commerce application ships thousands of items per day and sends email
  notifications for each one. This is a synchronous operation. This means
  that the item's ship status is saved in the database, and an email is sent.
  Now, on bad days, the email server goes down or crashes due to overload. So
  none of us receive the email notification.
  Assume we add a service layer between the shipment service and e-mail service.
  So, shipping service sends the shipment notification to the service layer,
  which will route the message to the email service. If the email service goes
  down, the service layer will store the messages. When the email service
  goes live,
  the service layer will push those messages to the e-mail service.
  And this service layer is nothing but a message broker.
  RabbitMQ is a distributed message and stream broker. A message broker is
  software that sits among applications, allowing them to exchange messages.
  RabbitMQ is useful for decoupling services, remote procedure calls (RPC),
  streaming services, and IoT.
  RabitMQ is most commonly used in microservice-based architectures. It
  operates asynchronously. This means they do not follow a simple request-response pattern, and we
  must wait for replies.
  RabbitMQ, like the postal service, sends messages from producer to
    consumer.
Producer
  A Producer is an action or event that generates
  messages. Credit card transactions, a drop or rise in stock price, or an order
  dispatch are all examples of Producers.
Consumer
  On the other hand, Consumers are the entities that
  listen to messages. Humans are the perfect example of a consumer. We
  consume everything, from news to alcohol. Jokes aside! Because a message broker might be connected to multiple producers and
  consumers, communication between them is asynchronous.
Exchange
  But, wait a second! How does the message broker get a message from the
  producer to the consumer? The answer is Exchange. It functions as RabbitMQ's brain. Exchange helps message
  broker to route messages from producer to consumer.
Queue & Binding
  A message broker may have multiple exchanges. Exchanges always receive
  messages from producers. Consumers are not connected directly to exchanges.
  Queues connect exchanges and consumers.
  Binding connects queues to exchanges. You can think of queues
  like our letterbox. Exchange pushes messages into queues, from which
  interested consumers can consume them.
  An exchange can be bound to multiple queues, and a queue can be linked to
  numerous exchanges. The consumer might also listen to messages from multiple
  queues.
Connection & Channel
  RabbitMQ is designed to implement the AMQP (Advance Message
  Queuing Protocol). AMQP is an open messaging protocol that defines the rules
  for message exchange, queueing, and routing in a messaging system.
  To communicate with RabbitMQ, a client or application must first establish a
  connection. A client can be either a producer or a consumer. The
  connection is established using either TCP or TLS. The main purpose of
  a connection is to establish a secure path between the client and
  RabbitMQ.
  A connection can have several channels. But, why do we need channels? We can set up multiple connections
  between the client and the broker to exchange messages. Keeping multiple
  TCP connections open at the same time is undesirable because it consumes
  system resources and makes firewall configuration more difficult. So,
  according to the AMQP protocol, channels are "lightweight connections that share a single TCP connection".
  We can use the amqp-client Java library to communicate with
  RabbitMQ in a Java application. This library is available through the
  Maven repository. We need to install RabbitMQ on our local machine to communicate with the
  Java application. You can find an installation guide
  here.
Producer & Consumer using Java
  Now, let's look at how to create a message and how to consume it using
  RabbitMQ and Java. First, we write a program that will connect and publish a
  message to RabbitMQ.
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.nio.charset.StandardCharsets;
public class Publisher {
    private static final String HOST = "localhost";
    private static final String QUEUE = "OWL-POST";
    private static final String MESSAGE = "Happy birthday Hermione!";
    public static void main(String[] args) {
        // CREATE A CONNECTION FACTORY
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost(HOST);
        // CREATE A CONNECTION FROM FACTORY
        try (Connection connection = connectionFactory.newConnection()) {
            // GET CHANNEL FROM CONNECTION
            Channel channel = connection.createChannel();
            // ASSIGN A QUEUE TO CHANNEL
            channel.queueDeclare(QUEUE, false, false, false, null);
            // PUBLISH A MESSAGE TO CHANNEL
            channel.basicPublish("", QUEUE, null, MESSAGE.getBytes(StandardCharsets.UTF_8));
            System.out.println(" Message sent : '" + MESSAGE + "'");
        } catch (Exception e) {
            System.out.println(e.getMessage() + ", " + e.getStackTrace());
        }
    }
}
  We have used amqp-client Java client library to communicate with
  RabbitMQ.
  RabbitMQ is running on our local machine, so the host is localhost. The
  queue name is 'OWL-POST'.
  Consumer should connect to this queue to consume message from producer.
  ConnectionFactory is a factory class that allows you to open a
  connection to RabbitMQ.
  First, we get a connection from ConnectionFactory, and then we create a
  channel. We create a queue using queueDeclare() method by passing the
  queue name. This queue is idempotent, which means that if it already exists under this name, it will not be
  created again.
  Next, we use the basicPublish() method to send our encoded message to
  the queue. The first argument of the basicPublish() method is the exchange
  name. Because we passed a blank string as the first argument, we are
  connecting to RabbitMQ's default exchange.
Here is our consumer.
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
import java.nio.charset.StandardCharsets;
public class Consumer {
    private static final String HOST = "localhost";
    private static final String QUEUE = "OWL-POST";
    public static void main(String[] args) {
        // CREATE A CONNECTION FACTORY
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost(HOST);
        try {
            // CREATE A CONNECTION
            Connection connection = connectionFactory.newConnection();
            // CREATE A CHANNEL FROM CONNECTION
            Channel channel = connection.createChannel();
            // ASSIGN A QUEUE TO CHANNEL
            channel.queueDeclare(QUEUE, false, false, false, null);
            System.out.println(" Waiting for message...");
            DeliverCallback deliverCallback = (consumeMsg, delivery) -> {
                String message = new String(delivery.getBody(), StandardCharsets.UTF_8);
                System.out.println(" Message received : '" + message + "'");
            };
            channel.basicConsume(QUEUE, true, deliverCallback, consumeMsg -> {});
        } catch (Exception e) {
            System.out.println(e.getMessage() + ", " + e.getStackTrace());
        }
    }
}
  So the consumer is connected to the 'OWL-POST' queue. And it receives the
  message via the basicConsume() method.
  DeliverCallback is a callback interface. It is notified when the
  consumer receives the message and is passed as an argument to the
  basicConsume() method.
Here is the message from Harry -'Happy birthday Hermione!'.
Happy coding!!! 😊






 
No comments:
Post a Comment