This is the second post in my series about the Oslo.Messaging library. The previous post gave a high level introduction to Oslo.Messaging. In this post we’ll dig a little deeper.
Climb Aboard the Message Bus
Before we go further I’d like to talk a bit about messaging middleware and how it relates to the Oslo.Messaging library.
Let’s start by thinking about messaging in the abstract. What do we mean by ‘messaging’? What does it involve? Why would we use it?
These are pretty easy questions for most of us to answer. But for the sake of completeness let’s cover these at a high level.
In general, messaging deals with the transfer of information between two parties. For our purposes we’re interested in the case where these two parties are software applications and the information passed is some form of digital data. The communicating parties are defined by the roles they play in the transfer of a message.
Senders and Receivers
The sender is the application that sends the digital data – the message – to another application for consumption. This consuming application is the receiver.
To be clear – we’re discussing a very simplified model. In reality an application can play either or both roles. But for now we’re keeping it simple. And by ‘simple’, I mean:
Great, so that’s all there is to it, right?
Not quite. I didn’t mention the concept of addressing. In order to send a message we need to know where to send it to, right? Just like an email, a message is associated with a destination address. This address identifies the receiver.
Pretty straightforward, no?
Well… no, not always. As with most technology, messaging can get fairly “feature rich” *
While there are plenty of use cases which fall into the pattern above – RESTful Web Services is one example that comes to mind – there are messaging patterns that aren’t suited to that simple send/receive pattern:
- Work Queue – this pattern consists of multiple worker and dispatcher processes. Each worker is identical in terms of the work it can do, and all workers share the same address. When a dispatcher has work that needs to be done, it sends a message describing the work request to that shared address. The request message is consumed by the first available worker. Since all workers are identical the dispatcher doesn’t care which worker services the request, as long as it does get serviced.
- Multicast – in this pattern there are multiple receivers listening on the same address. When a message is sent to that address each receiver gets its very own copy of that message.
- Store and Forward – what happens when a message is sent to an address and there are no receivers for it? It gets dropped. But what if that message is really important? Like “you won the lottery!” important?? What if the receivers are only available periodically – like at the close of business? Wouldn’t it be great if there was a way to hold onto the message (store it) until a receiver becomes available (forward it)?
I could go on, but you get the picture. In order to provide these types of messaging patterns we need more than just a sender and a receiver.
This “more” is the message bus.
A message bus is a specialized intermediary that sits between a sender and a receiver. Its job is to provide advanced messaging services, like multicast or store-and-forward, to its clients – the sender and receiver applications. Typically the message bus is a service provided by your IT infrastructure for use by various deployed applications.
Meanwhile, back in Oslo…
Now that you have an understanding of all the players in our messaging saga it’s time to get back to Oslo.Messaging.
Oslo.Messaging provides senders and receivers – or more accurately, messaging clients – with the means for interfacing with a message bus. Oslo.Messaging doesn’t offer any message bus functionality itself. Instead it is compatible with a few popular third party message bus solutions and is meant to be deployed using one of these.
No doubt you’ve heard of RabbitMQ. RabbitMQ is the default message bus for OpenStack. Oslo.Messaging uses the kombu client library for interfacing with RabbitMQ. In addition to RabbitMQ, Oslo.Messaging is compatible with several other message bus implementations:
- Apache ActiveMQ
- and its sub-project Artemis
- Apache Qpid Dispatch Router
- Apache Kafka (currently experimental)
- Apache Qpid C++ Broker
You can select drivers for any of the above protocols via the Oslo.Messaging Transport class. This class represents Oslo.Messaging’s connection to the message bus.
Oop! Look at the time! It’s getting late, and judging from the smell emanating from the kitchen Wifey has been up to her dinner magic again. It’s hard to blog on an empty stomach, so let’s save our exploration of the Oslo.Messaging Transport for another day…
* that’s industry jargon for “way complicated”