RabbitMQforMicroServicesCommunication

Using RabbitMQ for MicroSerices Communication

Decomposing your monolith app into multiple, totally independently deployable and scalable services.

The smaller apps are more modular with well-defined boundaries, can be written using different languages/frameworks, fail in isolation so that the entire app doesn’t go down (no SPOF).
Take a Cinema ticketing example:
image

microservices-based architecture

bad practce to have clients to communicate with each of the service instance separately.

Each service has its own storage

Enables decoupling
Some queries will then need to join data that is owned by multiple services. To avoid this major performance hit, data may be replicated and sharded. This principle is not just tolerated in microservices, but encouraged.

a single request should, ideally, only invoke one service to fetch the response

not always possible, mechanisms like gRPC, Thrift or even simple HTTP (as in our example) are commonly employed when necessary. As you may have guessed, this implies that data will have to be replicated across our services. Say, the GET /catalog/<> endpoint is also supposed to return the premieres at each cinema in the city at that time. With our new strategy, the premieres will have to be stored in the database for the Cinema Catalog service as well. Hence, point iii).

REST calls made to our API gateway

request ==> gateway ===> complies result || response to clients

Communication among services like this on one client request to the app should not happen. Otherwise we’ll be sacrificing performance, on account of another HTTP round-trip, for the newly introduced modularity.

Communicating Asynchronously Between The Services

the premieres change as a result of some CRUD operation on the Movies service. To keep the data in sync, that update event will have to be emitted and applied to the Cinema Catalog service as well

Try to picture our microservices as a cluster of state machines where updates in states may have to be communicated across the cluster to achieve eventual consistency.

Of course, we should never expect our end-users to have to wait longer for requests to finish and sacrifice their time for modularity to our benefit. Thereby, all of this communication has to be non-blocking. ### And that’s where RabbitMQ comes in. ###

RabbitMQ: implements the AMQP messaging protocol. first, you install a RabbitMQ server instance (broker) on a system. Then a publisher/producer program connects to this server and sends out a message. RabbitMQ queues that message and siphons it off to a single or multiple subscriber/consumer programs that are out there listening on the RabbitMQ server.

microservices are way more complex and we won’t be covering critical topics like fault tolerance because of the intricacy of distributed systems, the full role of the API gateway, Service Discovery, data consistency patterns like Sagas, preventing service failure cascading using Circuit Breakers, health checks and architectural patterns like CQRS. Not to mention how to decide whether microservices will work for you or not.

How RabbitMQ Works

Massages published to an exchange inside the RabbitMQ broker, then exchange copies of that message to queues on basis f certain developer-defined rules called binding. This journey called Routing.

the direction is non-blocking message transmissions. Not exactly. There are four different types of exchanges and each, along with the bindings, defines a routing algorithm. “Routing algorithm” means, essentially, how the messages are distributed among the queues. Going into the details about each type might be an overkill here, so I’ll just expand on the one we’ll be using: the topic exchange.

For an exchange to push a message onto a queue, that queue must be bound to the exchange. We can create multiple exchanges with unique names, explicitly. However, when you deploy RabbitMQ it comes with a default, nameless exchange. The exact way a binding key works, again, depends on the type of the exchange. Here’s how it works with a topic exchange:

  1. A queue is bound to an exchange using a string pattern (the binding key)
    The published message is delivered to the exchange along with a routing key.

  2. The exchange checks which queues match the routing key based on the binding key pattern defined before.

image
source:

Any message with a routing key ”quick.orange.rabbit” will be delivered to both queues. However, messages with ”lazy.brown.fox” will only reach Q2. Those with a routing key not matching any pattern will be lost.

For some perspective, let’s just skim over two other exchange types:

  • Fanout exchange: Messages sent to this kind of exchange will be sent to ALL the queues bound to it. The routing key, if provided, will be completely ignored. This can be used, for example, for broadcasting global configuration updates across a distributed system.
  • Direct exchange (simplest): Sends the message to the queue whose binding key is exactly equal to the given routing key. If there are multiple consumers listening on the queue, then the messages will be load-balanced among them, hence, it is commonly used to distribute tasks between multiple workers in a round robin manner.

//still need to follow up docker tutorial! and Circle.ci

https://codeburst.io/using-rabbitmq-for-microservices-communication-on-docker-a43840401819