Messaging or message queuing is a style of communication between applications or components that enables a loosely coupled architecture. Advanced Message Queuing Protocol (AMQP) is a specification that defines the semantics of an interoperable messaging protocol. RabbitMQ is an Erlang-based implementation of AMQP, which supports advanced features such as clustering.
In this chapter, we will cover the following topics:
Smoke signals, couriers, carrier pigeons, and semaphores: if this was a riddle, you would think of messages right away. Humanity has always had the need to connect with each other, finding new ways to defy the challenge posed by the distance between the different groups of people who need to communicate. We've come a long way with modern technologies, but essentially the basics remain. Senders, recipients, and messages are the core of all our communication infrastructures.
Software applications have the same needs; systems need to exchange messages with each other. They sometimes need to be sure that the message sent has reached its destination. They sometimes need to receive an immediate response, but not all the time. In some cases, they may even need to receive more than one response. Based on these different needs, different styles of communication between systems have emerged.
All this can be explained with the help of the following figure:
This request-response style of interaction is the most common style; a system (acting as a client) interacts with a remote system (acting as a server) via a synchronous interaction with a remotely exposed communication endpoint. Whether it takes the form of a remote procedure call, a web service invocation, or consumption of a resource, the model is the same: one system sends a message to another and waits for the remote party to respond synchronously. Systems communicate with each other in a point-to-point manner.
The advantages of this approach are met with inconveniences. On one hand, programmers get a simple programming model as everything happens in a procedural fashion. On the other hand, the tight coupling between both parties has a deep impact on the architecture of the whole system as it is hard to evolve, hard to scale, and so on.
Enter the one-way style of interaction, where systems interact with each other in an asynchronous fashion via the transmission of messages, and generally through the intermediary of relaying parties known as message brokers. In this scheme, commonly referred to as messaging or message queuing, systems play the role of message publishers (producers) and message consumers. They publish a message to a broker on which they rely on to deliver it to the intended consumer. If a response is required, it will eventually come at some point on time through the same mechanism, but reversed (the consumer and producer roles will be swapped).
The advantage of the messaging approach is that systems are loosely coupled. They don't need to know exactly where they are located; a mere name is enough to reach them. Systems can, therefore, be evolved in an independent manner with no impact on each other as the reliability of message delivery is entrusted to a broker. This is demonstrated in the following figure:
Indeed, the architecture represented in the preceding figure allows the following:
The main downside of this approach is that programmers cannot rely on the mental model of procedural programming where things immediately happen one after another. In messaging, things happen over time, so systems must be programmed to deal with it.
If all this is a little blurry, let's use an analogy of a well-known protocol: Simple Mail Transfer Protocol (SMTP). In this protocol, e-mails are published (sent) to an SMTP server. This initial server then stores and forwards the e-mail to the next SMTP server, and so on until the recipient e-mail server is reached. At this point, the message is queued in an inbox, waiting to be picked up by the consumer (typically, via POP3 or IMAP). With SMTP, the publisher has no idea when the e-mail will be delivered or whether it will eventually be delivered at all. In case of a delivery failure, the publisher can be notified of issues later down the line. The only sure fact is that the broker has successfully accepted the message it had initially sent.
Furthermore, if a response is needed, it will arrive asynchronously using the same delivery mechanism but with the publisher and consumer roles reversed. The entire process is demonstrated in the following figure:
With these fundamental notions established, let's now delve into the messaging protocol that we are going to consider in this book: Advanced Message Queuing Protocol (AMQP).
The Advanced Message Queuing Protocol (AMQP) is an open standard that defines a protocol for systems to exchange messages. AMQP defines not only the interaction that happens between a consumer/producer and a broker, but also the over-the-wire representation of the messages and commands that are being exchanged. Since it specifies the wire format for messages, AMQP is truly interoperable—nothing is left to the interpretation of a particular vendor or hosting platform. And since it is open, the AMQP community has flourished with broker and client implementations in a wide range of languages.
The AMQP 0-9-1 specification can be downloaded at http://www.rabbitmq.com/resources/specs/amqp0-9-1.pdf.
Let's look at the following list of core concepts of AMQP, which we will revisit in detail in the upcoming chapters:
You may have a message-queuing background and are by now wondering what are the main differences between AMQP and another protocol that you know. Here is a quick comparison of some of the main features:
Multiple commercial and open source implementations of AMQP are available. Often, existing messaging brokers have been extended with an AMQP adapter, like in the case of ActiveMQ.
The open source broker we will look at in detail for this book has been built from the ground to support AMQP. So let's now turn our focus on RabbitMQ.
3.141.35.185