Step 6: Explore Consumer Scaling Patterns
You've now completed Step 5: Try a Request-Reply Message Exchange Pattern.
In step 6, you'll expand your understanding by setting up three common messaging patterns used for consumer scaling.
As you've learned in the previous steps, Solace topics give you the flexibility to implement different message exchange patterns, such as publish-subscribe and request-reply, while also allowing each consumer to subscribe to the topics that give them exactly the events they want to receive. In this step, we'll learn how Solace allows you to further decouple your consumers from your producers by enabling consumer applications to scale in various ways, depending on their individual requirements. For more information about consumer patterns and consumer scalability patterns, see the Solace Ultimate Guide to Event-Driven Architecture Patterns.
In this step, we'll focus on three patterns that show consumer scalability options and use the Solace Try-Me CLI tool to demonstrate each of these patterns:
- Competing consumers
- High availability
- Partitioning
The most common way to implement these patterns is using Guaranteed message delivery with a queue. When using queues to implement these scaling patterns, producers still publish events to topics, and consumers bind to queues that are configured to meet their specific scaling requirements. The queues subscibe to the topics that the consumers want to receive events for.
Competing Consumers
Competing consumers is a scalability pattern in event-driven architecture that involves distributing the workload of processing events among multiple instances of the same application to improve throughput and reduce processing time.
In this mode, the queue has a non-exclusive access type, which facilitates the delivery of messages to all bound consumer flows in a round-robin fashion. This pattern is commonly used when message order is not important and you need to scale consumers to keep up with the message throughput.
Set Up Competing Consumers
In this exercise, we'll set up three competing consumer applications to share the message processing load. After you complete these steps, you'll have a consumer scaling pattern like the following animation:
To set up competing consumer instances, perform these steps:
- Open a command-line terminal window and create a non-exclusive queue with a topic subscription for
coffeeshop/>
. Enter the following command: - Open three additional command-line terminal windows and in each one, start a receiver with the following command:
- In another command-line terminal window, start a sender that publishes 100 events with an interval of 1 second between each publish using the following command:
-
You can verify the behavior in PubSub+ Broker Manager by going to your queue and viewing the Consumers tab. If all of your receivers were bound to the queue before you began sending messages, you’ll see the messages evenly distributed across the receivers.
stm manage queue --create NonExclusiveQ --access-type NON-EXCLUSIVE --add-subscriptions "coffeeshop/>"
You should see the following result:
ℹ info info: loading 'queue' command from configuration 'stm-cli-config.json' ✔ success success: queue 'NonExclusiveQ' created successfully ✔ success success: subscription to topic 'coffeeshop/>' added successfully ✔ success success: 1 subscription(s) found on queue NonExclusiveQ -coffeeshop/> ✔ success success: exiting...
stm receive --queue NonExclusiveQ
stm send --count 100 --topic 'coffeeshop/order/new/v1'
You should see the messages being received by your 3 receivers in a round-robin, competing consumers fashion. Using a non-exclusive queue allows you to implement the competing consumers pattern and load balance events across different instances of your consumer.
High Availability
When you implement a high availability (HA) consumer scaling pattern, you have multiple instances of the same consumer application available to process events. One instance of the consumer is chosen to be active and receives all events, while the other instances are on standby. If the active instance crashes or goes down, the broker automatically elects another instance to activate and starts sending all events to the new consumer. This pattern ensures that event processing continues as long as you have one instance connected and processing. This pattern is also sometimes referred to as Primary / Secondary or Primary / Secondary / Tertiary depending on how many levels of redundancy are required.
To implement this pattern, the queue has the exclusive access type. This access type allows multiple consumers to connect, but the event broker delivers events to only one of them. If the active consumer disconnects, the next consumer to receive events is randomly selected from the waiting pool of consumers. This pattern is commonly used when all messages in a queue must be processed in order.
Set Up Consumers for High Availability
In this exercise we'll set up three consumer applications for HA. Two of the consumers are in standby mode and don't receive messages unless the active consumer application becomes unavailable. After you complete these steps you'll have a consumer scaling pattern like the following animation:
To set up consumer instances for high availability, perform these steps:
- Open a command-line terminal window and create an exclusive queue with a topic subscription for
coffeeshop/>
. Enter the following command: - Open three additional command-line terminal windows, and in each one start a receiver with the following command:
- In another command-line terminal window, start a sender that publishes 100 events with an interval of 1 second between each publish using the following command:
-
You can verify the behavior in PubSub+ Broker Manager by going to your queue and looking at the Consumers tab .You should see that one of the three consumers received all the messages.
- If the currently active consumer disconnects from the queue, one of the remaining two consumers starts receiving events. If you want to see the change in action, restart the publisher and, while the publish is in progress, stop the currently active consumer by pressing Control+C (on Windows and Linux) or Command+C (on Mac). You can see that one pf the standby consumers starts receiving messages.
stm manage queue --create ExclusiveQ --access-type EXCLUSIVE --add-subscriptions "coffeeshop/>"
You should see the following result:
ℹ info info: loading 'queue' command from configuration 'stm-cli-config.json' ✔ success success: queue 'ExclusiveQ' created successfully ✔ success success: subscription to topic 'coffeeshop/>' added successfully ✔ success success: 1 subscription(s) found on queue ExclusiveQ -coffeeshop/> ✔ success success: exiting...
stm receive --queue ExclusiveQ
stm send --count 100 --topic 'coffeeshop/order/new/v1'
You should see the messages all being received by the first receiver that you started because you are using an exclusive queue.
Partitioning
Partitioning is a design pattern in event-driven architecture that helps to improve scalability while also maintaining message order where it’s required. You effectively split up a stream of events into partitions, which can then be processed in parallel. Order is maintained by partition instead of across the entire event stream. This pattern is common when you need to scale your consumers, but you also care about message order.
In PubSub+, this pattern is implemented using partitioned queues. Partitioned queues are a type of non-exclusive queue that delivers to many consumers at once to enable scaling. Partitioned queues use a partition key to split ingress events into partitions. All events within a partition are always delivered to the same consumer, thus enabling scalability while maintaining the message order. For more information, see Partitioned Queues.
You can also watch our Solace Developer Advocate demonstrate partitioned queues.
Set Up a Partitioned Queue
For this exercise, we'll set up partition keys and create a partitioned queue. You can set partition keys using the Solace Try-Me CLI using these parameters:
- Use
--partition-key <KEY>
to set keys based on the message publish time. - Use
--partition-keys <KEY...>
to specify a list of partition keys.
To set up a partitioned queue for the coffee shop, perform these steps:
- Open a command-line terminal window and create an non-exclusive queue with five partitions. Enter the following command:
- Open three additional command-line terminal windows and in each one, start a receiver with the following command:
- Open an additional command-line terminal window and start a sender that publishes 100 events with an interval of 1 second between each publish and passes a list of partition keys using the
--partition-keys
parameter. -
You can verify the behavior in PubSub+ Broker Manager by going to your queue and looking at the Consumers tab .You should see that one of the three consumers received all the messages.
stm manage queue --create PartitionedQ --access-type NON-EXCLUSIVE --add-subscriptions "coffeeshop/>" --partition-count 5
You should see the following result:
ℹ info info: loading 'queue' command from configuration 'stm-cli-config.json' ✔ success success: queue 'PartitionedQ' created successfully ✔ success success: subscription to topic 'coffeeshop/>' added successfully ✔ success success: 1 subscription(s) found on queue PartitionedQ -coffeeshop/> ✔ success success: exiting...
stm receive --queue PartitionedQ --output-mode props
stm send --partition-keys ESPRESSO DOPPIO AMERICANO LATTE CORTADO CAPPUCCINO MACCHIATO FLATWHITE BLACKEYE --count 100 --interval 1000 --topic 'coffeeshop/order/new/v1'
You should now see the messages being received by your three receivers. Notice that messages with the same partition key, such as ESPRESSO, are always delivered to the same consumer. The partition key appears as the JMSXGroupId user-attribute, which is displayed in the Solace Try-Me CLI tool when you use --output-mode props
.
Tutorial Steps
You've completed the sixth step in the tutorial. Click Next Steps for suggestions to continue your Solace journey.
Step | Description |
---|---|
|
Set up Your First Event Broker - Complete |
|
Solace EDA Basics - Complete |
|
Set up the Solace Try-Me CLI Tool - Complete |
|
Try a Publish-Subscribe Message Exchange Pattern - Complete |
|
Try a Request-Reply Message Exchange Pattern - Complete |
|
Try Consumer Scaling Patterns - Complete |
|
You can return to the main Tutorial page at any time.