FacebookLinkedInShare

What is Messaging

These days we seek new ways to manage complexity, reduce coupling, and improve scalability. Micro-Service though REST services are a good practice to do achieve such goal.

In scenarios when request requires several remote calls to other services it’s almost impossible to guarantee quick response time.

A good solution to this problem is to use messaging pattern (like: pub-sub). The main idea behind all message based systems and patterns is very simple:

  • You don’t call other applications through REST or SOAP synchronously.
  • You send messages to a message broker. The message broker will deliver messages asynchronously to other applications (or just workers inside your application).

As a result your application can respond without being blocked by external resources.

Message Broker

is an intermediary program module which translates a message from the formal messaging protocol of the sender to the formal messaging protocol of the receiver.

A message broker is an architectural pattern for message validation, message transformation and message routing. It mediates communication amongst applications, minimizing the mutual awareness that applications should have of each other in order to be able to exchange messages, it also has few advantages like: no need to manage storing and delivering messages, It guarantees delivery, durability and can provide some additional services such as filtering, logging, failover etc. The main advantage of a broker is that it effectively implementing decoupling.

AMQP Model

The Advanced Message Queuing Protocol (AMQP) is an open standard application layer protocol for message-oriented middleware. The defining features of AMQP are message orientation, queuing, routing (including point-to-point and publish-and-subscribe), reliability and security. example for AMQP models are: MSMQ, ActiveMQ, OpenMQ, ZeroMQ, RabbitMQ etc.

Some basics of the AMQP model:

  • Message Broker. A message broker is a system taking incoming messages from one application and delivering them to another. RabbitMQ server is a message broker.
  • Producer. It is a system sending messages to a message broker.
  • Consumer. It is a system receiving messages from a message broker.
  • Exchange. It is an entry point for all incoming messages. Producers send messages to exchanges.
  • Queue. It is an entity where all messages are stored. Consumers read messages from queues.
  • Binding. A relationship between an exchange and a queue.

AMQP Model With Ruby

There are a huge variety of ruby gems that can be used for message passing. On of the most popular gem is Bunny. Bunny is quit simple to use and it does not require any knowledge of Event Machine or asynchronous programming.

Why Bunny??

One can use Bunny to make Ruby applications interoperate with other applications (both built in Ruby and not). Bunny support simple work queues to complex multi-stage data processing workflows that involve many applications built with all kinds of technologies.

Bunny is a mature library (started in early 2009) with a stable public API.

Examples

(All examples taken from: Bunny Get Started)

You can use Rubygems to install Bunny

gem install bunny

Adding Bunny as a dependency with Bundler

source "https://rubygems.org"
gem "bunny", ">= 1.7.0"

Verifying your installation

Verify your installation with a quick irb session:

irb -rubygems
:001 > require "bunny"
=> true
:002 > Bunny::VERSION
=> "1.7.0"

“Hello, world” example:

Let us begin with the classic “Hello, world” example. First, here is the code:

This example demonstrates a very common communication scenario: application A wants to publish a message that will end up in a queue that application B listens on. In this case, the queue name is"bunny.examples.hello_world".

#!/usr/bin/env ruby
# encoding: utf-8

require "rubygems"
require "bunny"

conn = Bunny.new
conn.start

ch = conn.create_channel
q  = ch.queue("bunny.examples.hello_world", :auto_delete => true)
x  = ch.default_exchange

q.subscribe do |delivery_info, metadata, payload|
  puts "Received #{payload}"
end

x.publish("Hello!", :routing_key => q.name)

sleep 1.0
conn.close

001_hello_world_example_routing

You Can Do More…

  • one-to-many publish/subscribe (pubsub) example
  • many-to-many topic routing example
  • Using transactions