Danube: Queuing and Pub/Sub patterns
Danube is an open-source, distributed publish-subscribe (Pub/Sub) message broker system developed in Rust. Danube aims to be a powerful, flexible and scalable messaging solution.
Currently, the Danube platform exclusively supports Non-persistent messages. Meaning that the messages reside solely in memory and are promptly distributed to consumers if they are available, utilizing a dispatch mechanism based on subscription types
For comprehensive information on setting up, configuring, and using Danube, please refer to the official documentation and the previous article.
Client Libraries
To interact with the Danube Pub/Sub messaging platform, you can use the Rust or Go client libraries. Each library is designed to provide seamless integration and ease of use.
Rust Client Library
- Library: danube-client
- Description: An asynchronous Rust client library for Danube.
- Example Usage: Explore example usage for producers and consumers on GitHub repository.
Go Client Library
- Library: danube-go
- Description: The Go client library for interacting with Danube.
- Example Usage: Explore example usage for producers and consumers on GitHub repository.
Danube Binaries
The Danube release includes several binaries for running, interacting with and managing the Danube platform. Here’s an overview of the available binaries and how to download them:
- Danube Broker: The core component of the Danube Pub/Sub platform.
- Danube Admin: A command-line interface (CLI) for interacting with and managing the Danube cluster.
- Danube Pub/Sub CLI: A CLI tool for handling message publishing and consumption.
To download the binaries check the latest release.
- Docker Image: For those who prefer containerized environments.
- Docker Image:
ghcr.io/danrusei/danube-broker:v0.1.2
- Docker Image:
danube-pubsub CLI
The danube-pubsub
CLI allows you to produce and consume messages. Here are some example usages:
Produce Messages: To send messages to a topic, use the
produce
command:danube-pubsub produce -s http://127.0.0.1:6650 -c 1000 --message "Hello, Danube!"
Consume Messages: To receive messages from a topic, use the consume command:
danube-pubsub consume -s http://127.0.0.1:6650 --subscription "my-subscription"
danube-admin CLI
The danube-admin
CLI is used for interacting with and managing the Danube cluster:
danube-admin
CLI for managing the Danube pub/sub platform
Usage: danube-admin <COMMAND>
Commands:
brokers - check Danube cluster brokers info
namespaces - manage and view information about namespaces
topics - manage and view information about topics
Queuing and Pub/Sub (Fan out) workflows using Danube
This section describes the steps to set up and use Danube for messaging and queuing on Linux.
Setup Phase
Start the ETCD Instance
The etcd instance or cluster is responsible for the metadata persistent storage and cluster synchronization.
To start the ETCD instance, use Docker with the following command:
docker run -d --name etcd-danube -p 2379:2379 \
-v /home/rdan/my_projects/danube/./etcd-data:/etcd-data \
quay.io/coreos/etcd:latest \
/usr/local/bin/etcd \
--name etcd-danube \
--data-dir /etcd-data \
--advertise-client-urls http://0.0.0.0:2379 \
--listen-client-urls http://0.0.0.0:2379
Download and Run the Broker Instance
Download the Danube broker binary and start the broker instance with the following command:
RUST_LOG=danube_broker=info ./danube-broker --config-file config/danube_broker.yml
or RUST_LOG=danube_broker=trace for detailed logging.
Messaging Queuing Pattern Using a Shared Subscription
Queueing pattern: In a shared subscription model, messages are placed in a queue and distributed to all consumers subscribing to that topic. When a new consumer is added, the message load is distributed evenly across all consumers, ensuring that each consumer gets a share of the messages.
Traffic Distribution: The shared subscription pattern distributes messages in a round-robin fashion. This means that as new consumers join, the system redistributes messages among all active consumers, which helps in balancing the load and improves overall system performance and scalability.
Produce Messages
To send messages to a topic, use the produce command:
danube-pubsub produce -s http://127.0.0.1:6650 -c 1000 -m "Hello, Danube!"
The Message with ID 135 was sent
The Message with ID 136 was sent
...
The Message with ID 148 was sent
Consume Messages Using a Shared Subscription
To receive messages from a topic with a shared subscription, use the consume command:
danube-pubsub consume -s http://127.0.0.1:6650 -m my_shared_subscription
Received bytes message: 135, with payload: Hello, Danube!
Received bytes message: 136, with payload: Hello, Danube!
Received bytes message: 137, with payload: Hello, Danube!
Received bytes message: 138, with payload: Hello, Danube!
Received bytes message: 139, with payload: Hello, Danube!
Received bytes message: 140, with payload: Hello, Danube!
!!!! this is where I added the second consumer, notice the message id
Received bytes message: 142, with payload: Hello, Danube!
Received bytes message: 144, with payload: Hello, Danube!
Received bytes message: 146, with payload: Hello, Danube!
Received bytes message: 148, with payload: Hello, Danube!
Add Another Consumer to the Shared Subscription
In a separate shell, add another consumer to the shared subscription:
danube-pubsub consume -s http://127.0.0.1:6650 -m my_shared_subscription -c other2_consumer
Received bytes message: 141, with payload: Hello, Danube!
Received bytes message: 143, with payload: Hello, Danube!
Received bytes message: 145, with payload: Hello, Danube!
Received bytes message: 147, with payload: Hello, Danube!
Notice on Consumer Behavior
When the second consumer was introduced, you can observe that the messages are distributed in a round-robin fashion between the consumers. This distribution method ensures that messages are balanced across all available consumers, which helps in efficiently handling message traffic and improves scalability.
Messaging Pub/Sub (Fan-Out) Pattern
Pub/Sub pattern: The pub/sub (publish/subscribe) pattern allows multiple consumers to receive messages from a single topic, where the publisher sends messages to the topic without knowing who will receive them. Subscribers to the topic receive a copy of each message, enabling broad distribution and real-time updates across various consumers.
In Danube, by using multiple exclusive subscriptions, you can emulate the pub-sub pattern by effectively isolating different consumers. Each consumer gets its own dedicated stream of messages, allowing for independent processing while still benefiting from the message distribution capabilities of the system.
Produce Messages
To send messages to a topic using the fan-out pattern, use the following command:
danube-pubsub produce -s http://127.0.0.1:6650 -c 1000 -m "Hello, Danube!"
Consume Messages
To receive messages with an exclusive subscription, use the consume command with the –sub-type exclusive option:
danube-pubsub consume -s http://127.0.0.1:6650 -m my_exclusive --sub-type exclusive
Received bytes message: 37, with payload: Hello, Danube!
Received bytes message: 38, with payload: Hello, Danube!
Received bytes message: 39, with payload: Hello, Danube!
Received bytes message: 40, with payload: Hello, Danube!
Handling Exclusive Subscriptions
When using exclusive subscriptions, only one consumer is allowed per subscription. If you try to add a second consumer to the same exclusive subscription, you will encounter the following error:
danube-pubsub consume -s http://127.0.0.1:6650 -m my_exclusive -c other2_consumer --sub-type exclusive
Error: from status error: status: PermissionDenied, message: "Not allowed to add the Consumer: other2_consumer, the Exclusive subscription can't be shared with other consumers"
This error occurs because an exclusive subscription is designed to be consumed by only one consumer at a time. To add additional consumers, you need to create a new exclusive subscription with a different name:
danube-pubsub consume -s http://127.0.0.1:6650 -m my_exclusive2 --sub-type exclusive
Received bytes message: 372, with payload: Hello, Danube!
Received bytes message: 373, with payload: Hello, Danube!
Received bytes message: 374, with payload: Hello, Danube!
Received bytes message: 375, with payload: Hello, Danube!
Received bytes message: 376, with payload: Hello, Danube!
Summary
In summary, Danube offers an robust and efficient pub/sub messaging platform . With flexible subscription models, straightforward setup, it enables scalable, real-time messaging for diverse applications.