Message Brokers — the Nuances
What a message broker actually is, and how the three classic solutions — RabbitMQ, ActiveMQ and Kafka — differ: protocols, message models, delivery guarantees and partitions.
Prologue
I'm writing this one right after my lecture on integration types and message brokers.
A broker?
For better or worse, we're not talking about a stockbroker here, but about middleware — a go-between that shuttles messages between components of a single application, or between different applications in a distributed system. It takes messages from senders, routes them, and hands them off to receivers — taking on all the logistics of moving data around.
What a message broker can do:
- Message queue. Senders drop messages into a queue, receivers pick them up from there. That's how components talk asynchronously — nobody waits on anybody.
- Topics and subscriptions. Some brokers can do topics. A topic is a category: a sender publishes messages to it, and every subscriber of that topic receives them.
- Routing. The broker directs a message to the right receiver — by filters, by rules, or by other mechanisms.
- Delivery guarantees. Depending on the requirements, a broker offers different guarantee levels: "at-least-once", "at-most-once" or "exactly-once". We'll unpack these below.
- Fault tolerance. Some brokers replicate data and re-elect a leader on their own — the system keeps working even when a node goes down.
How do the 3 classic brokers differ from each other?
RabbitMQ
- Protocol: AMQP (Advanced Message Queuing Protocol).
- Message model: queues — a message goes into a queue, one of the consumers picks it up, and once read the message is gone!
- Delivery guarantees: supports different levels — "at-most-once", "at-least-once" and "exactly-once".
Apache ActiveMQ
- Protocol: several protocols to choose from — OpenWire, AMQP, MQTT and others.
- Message model: both queues and topics (pub/sub) — a message is published to a topic and fans out to every subscriber.
- Delivery guarantees: provides "at-least-once".
Apache Kafka
- Protocol: its own Kafka protocol.
- Message model: built around a log — messages are stored as a journal of records. It's a streaming platform: both stream processing and data storage.
- Delivery guarantees: strict message ordering and "exactly-once". Plus scalability and fault tolerance.
Message delivery guarantees
- At-Most-Once. A message either arrives or gets lost. No duplicates, but nobody promises delivery either.
- At-Least-Once. A message will definitely arrive at least once — but it may come through twice. No losses, though duplicates are possible.
- Exactly-Once. A message arrives once — no losses and no duplicates. The strictest guarantee level.
Now let's look at how each broker implements these guarantees:
RabbitMQ
- Flexibly configures guarantees through acknowledgements (ack for short);
- In queues you can require acknowledgement only after successful delivery — that's exactly at-least-once.
Apache ActiveMQ
- Also configures guarantees flexibly with different acknowledgement setups;
- You pick the level to fit the task — "at-least-once" or "exactly-once".
Apache Kafka
- Holds high guarantees thanks to the log model;
- Strict message ordering plus "at-least-once" and "exactly-once";
- A good fit wherever you need precise and reliable delivery.
A bit more on Kafka and partitions
In Kafka, data lives in topics, and each topic is split into partitions. Partitions are what let Kafka scale horizontally and spread the load across brokers.
How partitions work
- Data distribution. A topic is broken into several partitions, and each one holds its own ordered sequence of messages.
- Horizontal scalability. Partitions are spread across different brokers; each broker is responsible for one or several of them.
- Parallel processing. Different partitions are processed independently of one another — hence the performance gains.
- Load balancing. Each broker holds only part of the data, so the load is spread evenly.
Partition leader
- In each partition one broker is the leader, the rest are replicas.
- The leader serves reads and writes, the replicas keep a copy for fault tolerance and availability.
- A new message is first written to the leader, then replicated to the other brokers.
- If the leader goes down, one of the replicas automatically becomes the new leader — Kafka keeps working with no manual intervention.
More on partitions and Kafka's internals — in this article: it also covers the logic of segments and partition leaders.
Further reading
Originally published on my Telegram channel @it_underside.
Yours, DPUPP
Related Articles
Data Exchange Formats: From JSON to Protobuf
A deep dive into data exchange formats: where JSON lives, why XML still matters, what makes YAML great, and when it is time to switch to binary Protobuf, Avro, and MessagePack — tied to APIs and message brokers.
Message Brokers — the Nuances
What a message broker actually is, and how the three classic solutions — RabbitMQ, ActiveMQ and Kafka — differ: protocols, message models, delivery guarantees and partitions.
Copying Is Cheap. Running the Copy Is Expensive
Why "we built our own analog" and "we localized it" isn't innovation but a deferred invoice. A breakdown of what it costs to live on someone else's architecture and why sovereignty can't be bought on a Marketplace.