BASIC AMQP illustrated

After a little more than one year of heavy code production and few innovations, although I could explore some interesting stuff like WCF and RESTful, our team finally got a time to “invent” something new. This time, we have to rewrite a legacy system (mainly a single stored procedure *arghh*) that verifies the clients with overdue payments, notifies them about it and stop provisioning services until their debts are paid off. As it can be imagined, it has many responsibilities belonging to different domains, consequently, belonging to different teams of our company.

My team is responsible for verifying the financial issues and should inform another team, which takes care of services provisioning, about the debtors. Thus, it is necessary to define how our systems will communicate with each other. One of the suggested solutions was AMQP standard for message queuing and that’s exactly what I will talk about.

AMQP stands for Advanced Message Queuing Protocol and its main purpose is to enable full functional interoperability between conforming clients and messaging middleware servers (aka. brokers). That is, AMQP defines a standard protocol for publishing, queueing, storing and consuming messages. The message producer utilizes a client API to publish message into a server. The server/broker will then place the message into a queue and store it while it is not consumed. At last, a consumer application will accept the messages stored in a queue and remove them from it.

The AMQP overall model is represented below:

amqp_model

 

Server

An AMQP server, like RabbitMQ or Qpid, is a data server that accepts messages, routes them to different consumers (queues) according to some arbitrary criteria (bindings) and store the messages while not consumed.

 

Virtual Hosts

A virtual host is somewhat similar to a workspace where a user connects. It comprises a set of exchanges, message queues and bindings. Even though an user is authenticated into the server, it may not successfully connect into a virtual host if it is not authorized. The authorization for the server users are granted for each virtual host.

 

Exchange

It can be said that the exchange possess the most important role among the AMQP middleware server components. It is delegated to route the messages to the queues matching the routing information, like an routing key, with the previously set bindings. Exchanges can also route messages according to its type. Some of them are explained below:

  1. Direct: direct type exchange routes a given message matching exactly the message routing key with the queue binding key. This type of exchange is a MUST in AMQP server implementation.
  2. Fanout: fanout type exchange routes a given message to all bound queues regardless of it’s routing key. The fanout also is a MUST in the broker.
  3. Topic: topic type exchange routes a given message verifying if the message key matches the queue binding key. For instance, let’s suppose that we have created a queue belonging to an exchange of type topic and it is bound to the exchange with a binding key like “sport.#”. Now, imagine a message sent to the exchange with a routing key “sport.soccer”. The key “sport.#” says that any message with a key “sport.anything” must be routed to the queue with such binding key. The ‘#’ means matches zero or more words and ‘*’ means matches one word. Topic is a SHOULD be implement type in AMQP server.

 

Bindings

A binding is a constraint between a queue and an exchange, setting a criterion for message routing.

 

Routing Keys/Binding Keys

As explained above, routing keys are message identifiers. In the other hand, binding keys are bindings identifiers. Duh, you may say. I agree. But it is pretty much that. Binding keys exists to tell the exchange that a message with a key that matches the routing key should be addressed to its related queue.

 

Message Queues

Message queues are the consumer’s message inboxes. It keeps the messages in memory or disk until they are read by the consumer in a FIFO politics.

To illustrate AMQP messaging flow in a more comprehensible manner, let’s take a look at the following comic (special thanks to KreuZ for helping me with the figures), representing a Direct Type Exchange:

3-koma_02

3-koma_04

3-koma_06

In these frames, we have a Message producer that sends a message with a “cars” key to the Exchange. We have also two queues: John’s queue and Kate’s queue. John’s queue says that he likes “cars”. That is, he is bounded to the exchange saying that any message related to “cars” (binding key) is of his business.

When the Exchange receives the given message, he knows that John’s queue is interested in "cars”, Kate’s queue is interested in “cookies”, and that he has a message about “cars” in hands. So, with these information, he passes the message to John’s queue but not to Kate’s queue, since the message “subject” matches exactly with what John’s queue wants.

Well, that’s an introductory post about AMQP that I wanted to have it here because my next post will be about real code using AMQP implementations. For more information about AMQP, please refer to its site.

Finally, I hope that the illustration helps for a better understanding of the basic principles of AMQP protocol and I would appreciate your comments and mainly, suggestion and critics.

Tags: , , , , , , , , , , , ,

One Person has left comments on this post



» Daniel Cukier said: { Jul 31, 2009 - 04:07:56 }

Nice article! Very clear and soft explanation. Congrats!