Thoughts on Event Busses and Queues

An event bus can be a useful architectural pattern but you need to keep in mind the guarantees offered. PubNub, a hosted realtime events system makes guarantees about being globally distributed (so fault tolerant), scalable, and offers sub 250ms delivery of messages. If all you need is "fire and forget" messaging, their API is incredibly easy to use. If, however, you need to ensure that every message sent is delivered to some service for processing, PubNub is not the best solution (1).

The easiest way to guarantee the consumption of messages is to choose a broker that supports this behavior out of the box. Often times, this is defined at the protocol level and implemented by the server. Two common protocols that support this behavior are MQTT and AMQP. Two servers that support these protocols (amongst others) are RabbitMQ and ActiveMQ.

Two additional qualities to consider when choosing how to send messages are the number of times and the order in which messages are consumed. In the simplest case, a broker will guarantee a message is delivered "at least once", implying it could be delivered multiple times. If the operation you're running in response to a message is idempotent this is not a problem, however, there are cases where you want your broker to guarantee a message is delivered exactly once. This case can be supported however there is often a performance tradeoff (2).

The other quality to consider is the order in which messages are delivered. In a distributed environment, guaranteeing proper FIFO behavior is challenging, but can be done with a performance tradeoff. This behavior seems to be supported by RabbitMQ using the AMQP standard under certain conditions (3), however, there is no mention of this behavior being supported by the MQTT standard.

A word on AWS -- One solution I hear mentioned repeatedly is the SNS+SQS combination. While you can use those two products separately, as best I can tell, the combination is comparable to the likes of RabbitMQ. With respect to the message delivery concepts explained above, SQS specifically supports two different queues, standard and FIFO, which offer different tradeoffs between deliverability and performance (4).

  1. You can implement deliverability guarantees in PubNub at the application level, however, it'd definitely be preferable to have that built into the service
  2. This behavior is supported by the MQTT protocol via a QoS level of 2
  3. https://stackoverflow.com/questions/21363302/rabbitmq-message-order-of-delivery
  4. http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/Welcome.html