The concept of message queues is fundamental in message-oriented middleware (MOM) and a constant topic of discussion for Solace users. Generally speaking, a queue is defined as a storage area where a message is stored until it is consumed by an application, or it expires. A queue provides the guarantee that the message will never be lost even if the consuming application is unavailable or if the message broker crashes. Note that in addition to writing this blog post, I’ve also presented this concept in a video you can watch here.
Solace endpoints are objects created on the event broker to persist messages. There are two types of endpoints: a queue endpoint (usually just called a queue) and a topic endpoint. I detailed the differences here if you want to learn more, and in this post I’ll explain the two consumer patterns you have to choose from, how they differ, and when you should use each.
In Solace PubSub+ Event Broker, a message from a queue can be consumed by only one application, even though multiple applications can be bound to the queue. Based on the use case, a queue can have two access types for consumers: exclusive and non-exclusive.
When an application disconnects from the event broker, the endpoint it was connected to will buffer and save the messages destined for that application. If the application does not connect for a long period of time and the incoming message rate does not slow, the queue could run the risk of filling up. There is also the case where a consuming application cannot have downtime when processing time-sensitive data.
Using an exclusive queue, a developer could connect multiple instances of an application to the same queue to ensure messages are always processed. The first instance to connect, or bind, to the queue will receive all messages; should that instance of the application disconnect, the next instance that connected to the queue is prepared to take over activity and start consuming. This provides a fault tolerant method to consuming data from a queue without any downtime.
Note: Topic endpoints do not support multiple consumers when set as exclusive, therefore this fault tolerant consumer pattern only applies to queues.
For the developers out there, it may be useful to know there is an Active Consumer Indication which indicates to a previously standby consumer they are now the active consumer. This can be useful for grouped applications to function properly in a fault tolerant consumer pattern.
For some use cases, the ingress rate (publish message rate) may be too fast for a single endpoint consumer to keep up. It may be required to have multiple instances of an application share an endpoint and consume data in a load-balancing manner.
A Solace non-exclusive endpoint allows multiple connections to bind to it and messages are round robin distributed to those connected applications. There is also a consideration for the speed of each consuming application, meaning that messages will be sent to the consumer based on how fast or slow the consumer is. Based on the acknowledgment rate from the consumer, the broker will deliver the messages at the appropriate rate. This is often referred to as a competing consumer pattern.
For example, in the below diagram, both Application A and Application B will get messages. If both applications are processing messages at the same rate, the broker will deliver an equal number of messages to both apps. However, if Application B slows down, then based on the acknowledgment rate back from Application B, the broker will be able to identify Application B as a slow consumer and send the messages at the appropriate rate to Application B. The broker takes care that consumer applications are never pressured, and therefore acts as a shock absorber.
Both a queue and topic endpoint support this ability. While its default state is to support only one consumer, a non-exclusive topic endpoint can support multiple consumers.
The maximum number of consumers on a single endpoint can be configured on the endpoint itself, with the following exceptions which only allow for one consumer:
The good news is that all this complex logic is done by the broker behind the scene without any manual intervention by the administrator. The only thing that an administrator must decide is whether the queue is exclusive or non-exclusive. This can be done while the queue is being created or can also be done at a later date.
This Solace message queue property can be changed without any downtime. Changing this at runtime will cause consumers to disconnect, however, properly written applications should automatically reconnect; when they do, the queue will start behaving with the changed value.
The access type to use will depend on the exact use case. Both access types have their benefits. The main deciding factor should be whether message ordering is important and if applications need to run in parallel to increase the overall throughput.
These two access types can be combined together for some complex use case requirements like sticky load balancing or consumer group pattern. Read the blog post on sticky load balancing for a detailed explanation.
I hope this post has helped you understand the concept of access types, and how and when each access type should be used. If you found this post useful, you can visit the queues section of our docs and our PubSub+ for Developers page for more information. You can also check out some sample code on Github.
You can also read more in my series about understanding Solace endpoints by visiting the posts below:
Here’s the video version of this post that I mentioned above: